Nasty Security Issue

Yesterday a colleague asked me to help with a security issue he was having.  He is someone who I consider to be a good developer; but does not have a good understanding of Windows security beyond the basics…Right click on folder -> Properties -> Security.

The problem manifested as this developer (only) loosing access  to a NAS share – “it used to work”.

First I confirmed that he was in the correct Active Directory (AD) groups and those groups had sufficient permissions to the folders in question.  Check.  Conclusion – it should work.

Then I had the developer write a quick web application to make sure he was passing his full credential to web server.  Check.  Conclusion – not something that is globally impacting authentication/authorization.  Seems to be something in the “conversation” between this workstation and the file server.

Hmmm.  Next thing was to try this from another workstation.  He remoted into a old Windows XP workstation.  It worked!!  Conclusion – something going on with his workstation.

Now I know that on my laptop, when I log into Windows but I am not connected to the network – I am using a cached credential on my workstation.  I also know that part of that credential is the groups that I am a member of.  So it seems that what this particular workstation is passing to the file server does not have the right groups since the server is denying the request.  Seems like there is something dirty/broken in the cache.

I typed “windows delete cached credential” into my favorite search engine and got this post.  We followed the steps that Ashok spells out…

  1. From Control Panel\All Control Panel Items\User Accounts click the username To the left you will see Manage your credentials.  From that select the share name and remove.
  2. Delete using net use Start > Run > cmd > net use * /DELETE

…and shazam…it worked.

There is a first for everything – this was definitely a first.

Now onto a nasty SharePoint issue that I have been putting off.   Hey at least I may end up with another blog post.

Debugging 101

We had a very nasty issue yesterday (into today) at work.  It involved an issue we saw once before, last year, and never figured out what the issue was.  Well it was back yesterday and it reminded me of some of the important aspects of problem resolution; closely related to debugging skills.

The specifics of this issue are not really important except in that the infrastructure of the system has multiple physical tiers and that it is a vendor application hosted internally.  Multi-tier applications have a higher level of complexity that comes from the fact that there is way more code running that just the application itself (VIPs, routers, firewalls, communication stacks, different platforms, etc).  Vendor applications can just be a pain since you don’t know the internals of what is going on; which means you are making assumptions (aka educated guesses) sometimes. 

Below are a couple of my favorite principles when debugging a issue.

Write Everything Down

  • This not a time to test your powerful memory skills.  You will get tired and you will forget.  As you try things you will find things that work and things that don’t.  If you are lucky you will find the fix quickly. If you are not (it took us 20+ hours this time) then you will have many things that did not work.  These are very important and you are going to probably have lots of them
  • You are going to have people rotating in and out of the virtual team that are going to be a distraction if you have to bring each of them up to speed on what you have already tried.
  • You will resolve this issue at some point and want to restore some of the things you changed.  Write down the current state of the system – “which knobs have been turned”.
  • You may look back on the path you followed to resolution and be able to identify ways to improve the system overall.  If you write this stuff down you will appreciated a couple days later when your life returns to normal.
  • Names and phone numbers.  If you have an diversified organization, as we do, you are going to need/get lots of people coming and going.  Many of these folks will have knowledge of or authorization to change things that you do not. Once they are members of the virtual team you want to keep them since they already have a context which in and of itself is valuable.

Change One Thing a Time
Thankfully this is something that I learned very early on and have tried to live by.  I use the word tried, because I have succumbed to temptation to do otherwise and often lived to regret it.  My implementation of this principle is the following…

  1. Draw a conclusion about what you think is wrong.  In other words don’t go shooting in the dark.  If you don’t know what to do next then stop.  It doesn’t mean that you won’t be doing something soon, but don’t go trying things without first knowing what you think may be the issue may be.  At some point your conclusion will either be correct and you have “solved” the issue or it won’t be and you have eliminated another thing that is NOT the issue.  More on what does not work later.
  2. Evaluate your options for correcting.  Write them down; you may want to try all of them.  This is a good time for brainstorming.  You may want to bring some others into the virtual team for a short time to help out here.  Treat them as consultants (see roles and distractions below) and don’t let them linger too long unless they are able to fit in.
  3. Decide your approach for correction.  One person owns the decision as to what the next course of action is (see roles).  There a million ways of coming to a decision that I will not go into – the key here is that you choose one and let everyone know what the decision is.
  4. Plan your implementation.  This is not as heavy as it may sound.  You don’t want to spend too much time here; not that it is a waste, but at some point in this discussion you will get to a point of diminishing returns.
    1. Identify what you believe the new outcome will be.  
    2. How will you know if it worked?  
    3. Do you know how to roll back the changes you made?  
    4. How are you going to test your change? 
    5. What can go wrong?
    6. What may other outcomes be and what do they tell you?
    7. All things to consider BEFORE you actually implement the change.  I feel another who blog topic just on this point.  If you don’t understand why all these are important things to consider; then I need way more space than I want to spend here to show you why…so I won’t.  Trust me.
  5. Implement the change.  
    1. Identify who is going to do what and make sure they are clear on what they are changing.  Hopefully they are an expert and not learning as they go. 
    2. Pair programming was never more helpful than now.  Work together to ensure accuracy.   You will be getting tired and mistakes will happen.  Put everyone to use here and let them help by watching for gross errors.  Don’t be afraid to show someone how this works; you don’t want the fireworks effect where every time someone types something the entire rooms gasps.  This take patience, it hard to watch someone else type and it is equally hard to be watched.
  6. Run your test.  This is what we have been working for.  Write down the result(s).  Did something totally unexpected happen?  What does this tell you?  What conclusions can you draw?
  7. Repeat.  Look this iteration of conclusions, options, predictions and outcomes and decide what you going to do next.  Do you start over at step 1?  Or someplace in between here and there?
  8. Don’t forget to reset.  You need to choose to restore/reset the environment.  Record what you do and make sure everyone knows the current state. 

Clear Roles and Responsibilities
Important to consider and feels kind of bland in some ways.  Not to mention that this is probably a whole entry in itself.  A couple of things I wanted to record now are..

  1. Who is running the show? Make sure they can delegate.  Make sure everyone respects the decision when it is made.
  2. Who is communicating?  Boy this is a big topic in itself…
    1. What are the different audiences?
    2. Who make the decision to communicate?
    3. Is this the same/related as escalation?
    4. Frequency?  Email?  Phone?  etc.
    5. Blah, blah, blah…
  3. Who is a spectator?  Make sure they know they are.

A good example of poor role definition happened to us during this most recent incident.   The system came back up and an excited member of the team sent an email to the entire customer base that the system was available.  Whoa!  Yes the system did come back up but it was not ready for the business to start using it yet.  We still had not assessed why the system came back up and whether we thought our success was going to last.  What a pain if the system failed a couple minutes later.  Also, the system was still in a debug mode.  We had lots of logs turned on and test settings configured that need to be changed in order to get the system back to it’s production state.  Luckily the users figured out that someone was not quite right and let us know.  We recovered before anything really bad happened but it could have gone horribly wrong.

Did I follow my own principles this time?  I tried.  But sometimes when you have lots of people involved it is just not possible.  People get anxious and/or want to contribute.  They have good intentions but in the end it muddies the whole thing.

In our case we had a couple people off in the corner of the room trying things.  One with elevated privileges and the other with a little bit of knowledge but not a core member of the team.  They started hacking around and without anyone else knowing.  They changed a bunch of things on a test server and found that production environment was back up.  The likelihood that they actually did anything is very low, but now we don’t know since we don’t know what they did or the state of the environment before they did it.  Chaos.  Now we are left with a nagging question.  This has left me with a couple new principles.  It is not very well thought out at this point but I wanted to get it down now before I forgot.

Eliminate Distractions
Distractions come in many forms and they can slow you down or just plain hurt.

  1. Don’t have anyone involved that does not to need to be.  Excitement tends to draw crowds, so you need to know when to put up the yellow tape.  I don’t want to be militant about this because there are some people out there that are comfortable being in a peripheral role (see above) and know when to contribute and when to stay out of the way.
  2. Get to a war room or isolated area that makes all the other principles easier.  
    1. We have several big rooms with 80″ smart board/displays and lots of whiteboard space; which can aid in the documentation.  
    2. They also have table mounted speaker and lots of ceiling speakers for good audio because you will likely have a distributed team and communication with all them is going to be hard enough – forget it if you cannot hear one another.
    3. Getting away from the crowds can keep the crowds away.
  3. Don’t forget the creature comforts; food, drink, restrooms.  These are obvious things that the team will need during a incident; but they can also be distractions.  If the restrooms are way far away; then it just hurts.  If people are hungry they can be distracted.  You also don’t want everyone fending for themselves if you don’t have to.  I kept bringing in food for the team
  4. Get sleep when you need it.  No heroes. If you are getting punchy then are probably going to become a distraction for the entire team.  There are all kinds of studies out there that related being tired to being drunk – don’t debug drunk.  You will swerve over the yellow line.

Understand Vendors in Scope
Make sure you understand the vendor products or services in your application before you have an issue.  What support arrangement do you have with them?  Is it 24×7?  How do you reach them?  Make sure the contact information is current.  What is their engagement / escalation model?  Do they know your environment?  If not how are going to educate them?  Are you sure that the sharing technology (webex, etc) hey use is compatible inside your firewall?  Are you current/do they support the version you are on?

More to say here, but I am running out of steam.  I may revisit this at a later time.

Deep breadth.  I am down here at the bottom of this long entry and liking the brain dump.  Not sure how coherent it all is but it feels pretty good.  Let me know if you find any of this helpful.

As I was wrapping this up I found this interesting article that I though was worth linking to here.  I am constantly amazed at how many topics there are “out there”.

IIS 401.5 Error

Had a really weird problem today where I was getting a IIS 401.5 error on a subweb today. The problem shows up as a 401.2 error in the browser, but when you look at the IIS log it’s reported as a 401.5.

I was running through all my usual ways of debugging these types of issues and non of the usual things worked. Asked a collegue for help because I must be missing something obvious. Then I was verbally walking him through the configuration and I mentioned that the problem was only happening on this subweb. Something clicked on both our faces – it’s a subweb so there is more than one web.config in play here. I checked the web.config file and found that it was busted (the root site did not work either – but no one cares). I renamed the web.config file and bang, the site started working again.

Blogging this on the off chance it helps someone and to get it to stick in my own memory for next time.

C# – Keep me from hurting myself

I just fixed a funny bug where it was behaving very odd and it was because I had a return statement where I intended to have a continue. I musta looked at that line a dozen times and did not think anything of it. Just went back to the basics of debugging and ran through the code line by line, iteration by iteration. What an embarassing relief!

[Upon further reflection]
What if there was new language feature that made this less likely to happen. Does it help readability and/or intent? Take the following loop.

foreach (var i in theCollection)
if (i.Visible == false)

// other code goes here

What if I could change the syntax to something like this…

foreach (var i in theCollection)
except i.Visible == false
// other code goes here

Upon futher thought what if I just used LINQ instead?

var iVisible = theCollection.FindAll( i => i.Visible)

foreach( var i in iVisible)
// other code goes here

Not to bad from a syntax point of view. I don’t like that I am making a shallow copy of the original list for the purposes of only iterating through it. The language extension above works on the original list.