How would you replicate CFIMPERSONATE?

This post is more than 2 years old.

A friend recently asked me an interesting question. He wanted to use ColdFusion to read a folder that the server didn't have access to read. In the old days, you could get around this by using cfimpersonate. As you probably guess, this tag let ColdFusion impersonate another user when executing commands. This tag was removed when MX was released. So how would you go about doing the same thing now in ColdFusion 8?

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA

Archived Comments

Comment 1 by Tom Mollerus posted on 2/21/2008 at 11:48 PM

OK, I can think of one way that might work, at least for a *nix box: read in a text file (which lives outside of the web root, of course) that contains a username and password. Then run cfexecute with a sudo command to it to run as another user. For example, "sudo -u [username] -S [password] -s [command]".

Comment 2 by Brian Swartzfager posted on 2/21/2008 at 11:57 PM

I have a few CF apps where a single user can have different roles, so a technical administrator can take on the role of a power user by using a role-switching tool in the app.

When the user logs in, a User object is created for them and stored in session. Two of the properties of the object are currentRole (which denotes the current role of the user) and possibleRoles (a comma-delimited list of all the roles the user is authorized for). When the user goes to the role-switching tool, the list of possibleRoles is parsed and displayed, and the user can choose a different role, and that role replaces the value in their currentRole.

Your reader would have to do it a bit differently since they want to let the user take on a different individual identity, so they'd want to have a third property ("trueUserId") that doesn't change in order to preserve the user's real unique ID, but the principle is similar.

Comment 3 by Raymond Camden posted on 2/22/2008 at 12:02 AM

brian, sorry if this wasn't clear - but this question pertains to OS users. Not web site users. Ie, I need CF to act like Windows user Bob, or Linux user Mary. You get the idea.

Comment 4 by Brian Swartzfager posted on 2/22/2008 at 12:22 AM

Oops, my bad! But I guess that explains why I was unfamiliar with the cfimpersonate tag: I've never had to mess with users' OS rights.

Comment 5 by Sammy Larbi posted on 2/22/2008 at 12:26 AM

I don't know how to do it with CF, but could you write a DLL in .NET to do the dirty work, and call it using CF?

Comment 6 by john b posted on 2/22/2008 at 12:35 AM

what about using the windows RUNAS command from dos via a cfexecute - windows equivant of sudo, pipe the results into a folder CF can read and then access it and clean it up for render....

Comment 7 by Matt Osbun posted on 2/22/2008 at 12:44 AM

IIS-only solution, but you could give is IUSR account access to that folder. Seems the simplest route.

Comment 8 by john b posted on 2/22/2008 at 1:12 AM

but in that case CF would be running as SYSTEM (assuming it's a default config) so CF wouldn't have access even if IIS did via IUSR.

Comment 9 by Brian posted on 2/22/2008 at 3:14 AM

Build a batch file with the first command of:
net use z: \\server\share /user:specialuser password

then execute it with cfexecute and reference your z drive

Comment 10 by Jeremy Prevost posted on 2/22/2008 at 6:50 AM

I'd probably run Coldfusion as it's own Windows user (i.e. not the default of 'system') and assign it access to whatever folders you want it to have access to. In fact, that is what we all probably SHOULD be doing anyway...right :)

Comment 11 by Ben Davies posted on 2/22/2008 at 7:24 AM

We do what Jeremy suggests and have a special sa_coldfusion domain account. The Coldfusion services run beneath that account. This is a pretty easy workaround but it has some serious problems:

1. If you need some serious super-user rights, having the CF server possess those rights 100% of the time is troubling in some circumstances.

2. It puts the emphasis on the application level security to control what the server is doing for which user. When those rights are already managed at the OS or domain level, this is duplication and therefore it can be hard (or worrying) to have to keep application and os/domain permissions in sync.

3. Sometimes the scale of rights required is too huge and/or impossible to maintain. For example, if I want to use the CFEXCHANGE tags for a range of mailboxes without delegation I need to harass users for the domain passwords per session (No way I want to store it). Which seems stupid when the IIS security has already authenticated the user. The only way to avoid this is to create a super domain account with access to all mailboxes you are interested in delegated. For a large number of users this would never be approved.

4. For some tags the process user isn't even applied to the operation and usernames/passwords need to be supplied each time. This is awful - I hate passwords appearing in cleartext in my applications.

Some of these problems can be coded around. For example, if you nominate a domain group as containing members requiring access, you could conceivably keep your application rights in sync with the domain or OS simply by looking up the domain group or using CFNTAuthenticate.

The interesting thing is that whilst my problems are pre-dominantly Windows related, the same problems don't exist in the ASP/IIS world. In that realm, it appears you can actually impersonate the currently user (without needing any passwords) because Windows knows it can trust IIS. But CF can't be a trusted link in the chain of ISS - Coldfusion - OS/network

So I don't have any real solutions. Only problems. But I'm interested in other people's approaches.

Comment 12 by Scott P posted on 2/22/2008 at 7:53 AM

Ben hits on my issue. I know that I can create another service account and give it permissions. What I would like to see is cffile, cfdirectory, and cfcontent have a username and password attribute so we could pass in the user we want it run as. An example of the need would be accessing the user's home directory in a windows environment.

Comment 13 by DanaK posted on 2/22/2008 at 8:54 PM

I'd do what Jeremy mentions and give CF its own user to run the services etc. We then isolate that user to whatever permissions they need to avoid spillage. As Ben mentions however, this is really explicit to the environment you are in and the needs of the application/server.

Comment 14 by Pat posted on 4/28/2009 at 11:30 PM

So why WAS cfimpersonate removed from MX?

Comment 15 by Raymond Camden posted on 4/28/2009 at 11:37 PM

CF5 and earlier was all C code, MX was a complete rewrite. So I'd assume the code used for cfimpersonate didn't run with Java.