How do you change your password when you don’t know what your password is, and the only way to change your password is by knowing what your password is?
This puzzle actually has roots that go back several years. Sit back and relax, because I like telling stories. Deal with it.
My employer makes extensive use of Salesforce. I’ve been there for almost five years now, and their reliance on it hasn’t diminished in the least. We use it for multiple things, but among others, we use it to keep track of communications that we’ve had with our clients — phone calls, emails, smoke signals, blood sacrifices, that sort of thing.
At the time I started, Office 2007 was the standard corporate email client at our company, and Salesforce provided a plug-in for Outlook that would simplify the task of logging communications — emails in particular — we simply hit a button, told it which contact and company the email was related to, and the plugin would send our email and simultaneously add a copy of it to Salesforce. That way, if anyone had to take over one of our clients, they could see what we’ve been talking to them about without asking us for a 5-page report or sneaking onto their workstations when they left them unlocked (which we NEVER did). The plugin worked well enough most of the time, although occasionally you’d have to restart Outlook or uninstall the plugin and reinstall it.
Then, one day, an interesting thing happened — I got an MSDN subscription. My team was essentially a technical support team, and to even get the job, I had to show that I knew at least one programming language. Our manager, as a way of helping us grow and learn new things, reached out to a company that offered online training courses, in things like C# and .NET (along with a wealth of other things that I can’t remember), and arranged for a 60-day trial of their platform. At the same time, she arranged with our IT department to get us all MSDN subscriptions. Keep in mind, I’ve been programming since I was 9 years old, so I wasn’t terribly interested in the training courses (although I did try a couple of them and learned some interesting things, like how to do inline queries using LINQ). I was, however, interested in the MSDN subscription — I worked for another company, years ago, that had one of those, and I knew how dangerous those things could be. (If you’re not familiar with what an MSDN subscription is, let me sum it up in six words: shit-ton of free Microsoft software.)
As I’m browsing through the catalog on Microsoft’s website, I noticed that Office 2010 was available. I hate using old, outdated software (which is why I’m using Windows 7), so I downloaded it, generated a key, and installed it on my machine. Right away, however, I noticed a problem — the Salesforce plugin caused Outlook to crash as soon as it started. The plugin had been written back when dinosaurs roamed the earth, engineers wrote code by carving it into cave walls, and the current version of Outlook was Outlook 2003; it just wasn’t up to the task of working with modern software. Too bad, I thought — I won’t be able to use the Salesforce plugin any longer.
Then, a lightbulb went off in my head — I could just write a replacement. I didn’t know anything about the Salesforce API, but I knew how to program in C# well enough, Visual Studio made writing Office plugins quite easy, and Salesforce had plenty of documentation for their APIs out on their website. With some finagling, and a copy of their WSDL passed to me by one of my coworkers, I learned how to use Salesforce’s SOAP API and managed to get things up and running. Eventually, I churned out a working replacement, and even managed to improve in several areas over the old plugin. It was very popular and even went global (I got emails from teams in Asia asking me questions about it). It was, however, never officially sanctioned by our company, so it remains to this day something of an underground tool.
Things worked great for a while, but then something happened — our company decided to switch to single sign-on (SSO). It’s great from a UI perspective — employees no longer have to remember their Salesforce password — but I sensed that it would cause problems for my plugin. The API authenticates you by your email address and password — same as when you sign on to the website. Even when you use SSO, Salesforce still maintains a password for you — you just never use it, because they authenticate you by sending you to your company’s federator instead and letting them authenticate you. At first, it didn’t cause problems — people’s passwords didn’t change right away, and when their passwords expired, my plugin had code to detect this and let them change their password from within the plugin. But as time went on, new employees came on to the company (who were never given a Salesforce password), others had their passwords expired and never changed them (because they weren’t required to), and still others simply forgot what their password was.
For the most part, I ignored these issues. It had been some time since I initially developed the plugin, it was stable, people weren’t complaining about it, and I had moved on to other things. A few weeks ago, however, I was forced to confront this issue.
One day, my manager asked me to fill in some information on some of my Salesforce records. When I went to go fill in this information, however, I noticed that the fields weren’t there. When I went back to my manager with this information, he said “oh, your permissions must not be right. Let me email the Salesforce admins.” Things went downhill from here.
The Salesforce admins, in their infinite wisdom, did not fix the permissions on my account; instead, they deactivated my account and created a new one with the right permissions on it. When I got the email back from my boss letting me know what happened, a deadpan expression of “oh, yay” went through my head.
By this time, I had moved on to using a Mac. Not knowing how to program for the Mac, I searched around and discovered that Maildrop did pretty much the same thing as my plugin. Maildrop operated in pretty much the same way — it used your email address and password to talk to the Salesforce API. When I went to reconfigure Maildrop to work with my new account, I realized I didn’t know what my password was, so I went into Salesforce and tried to change my password. That’s when I noticed what a catch-22 it was:
- I didn’t know my password, because this was a brand new account and I had never been given an opportunity to set one.
- To change my password, I needed to know my old password.
- To use their “forgot your password” feature, you need to set your security questions and answers.
- To set your security questions and answers, you must know your password.
So the question arises — how are you supposed to set a password so that you can use the Salesforce API?
At this point, one of my coworkers pointed out the most obvious solution — email the Salesforce admins and ask them to reset my password. But for someone like me, that was as bad as stopping to ask for directions — I just couldn’t do it. I knew there had to be a way to do it on my own. But how do you do it?
The answer is that you do it through the Salesforce API. The API offers the
method, which allows you to set a new password for your account. You don’t need to supply the old password — just the new one that you want to set it to. I was familiar with this method, because my plugin used it when it detected that the user’s password had expired…after it prompted the user for a new one, of course.
But there’s a problem with this approach — to use this call, you first have to log in; and to log in, you have to know your email address and password.
Well…at least, that’s how it’s supposed to work.
When you log in to the Salesforce API, the API gives you back a session ID. The session ID is what authenticates you on all future API calls. As it turns out, the website does the same thing — it just puts the session ID into a cookie instead of showing it to you. After you’ve played around with Salesforce for a while, you start to learn that the two are interchangeable — for instance, if you’re looking at a particular record in your software, but you want to see more detail on it, the software can send you to that record on the Salesforce website. The software can let you bypass the login page by appending the session ID to the URL.
Now, we have a loophole. At this point, all I had to do was log in to the website, grab the session ID out of the cookies (Chrome’s developer tools make that part easy enough), and throw that into an API call.
I’m horrible at writing out SOAP calls by hand, so I wrote a piece of software and relegated this task to it. I even managed to work in a simple browser control — you just give it the URL of your Salesforce instance, it opens up a form with browser control, sends you to the website and lets you log in. Once you’re logged in, it can grab the session ID out of the cookies for you.
Sure enough, all I had to do was go to my company’s Salesforce website, let SSO do its magic, and then grab the session ID out of the cookies. Once I had a session ID, I was able to throw that into an API call, choose a new password, and make the
call. Problem solved. I can now get to the API, set my security questions, and change my password in the future.
If you want to see the fruits of my labor, I’ve included them below. The first one is the source code (as a Visual Studio 2010 project); the other is the compiled, ready-to-install version.