Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you perform an impersonated search in SharePoint without providing a password?

I have done impersonation in SharePoint quite a bit in the past by doing something such as the following.

SPWeb web = SPContext.Current.Web;
string currentWebUrl = web.Url;
SPUser user = web.EnsureUser(loginToImpersonate);
using (SPSite site = new SPSite(currentWebUrl, user.UserToken)
{
    using (SPWeb impersonatedWeb = site.OpenWeb())
    {
        // Any SharePoint access here to 'impersonatedWeb'
        // is impersonated as 'loginToImpersonate'
    }
}

Note that this does not require the password of the user you are impersonating, but does require certain code access security to run. As a side note the EnsureUser call also requires the current user to be an admin, but there are other methods that can be used in place of EnsureUser to get the SPUser object (trying to keep my code fragment simple for this question).

Now that I've set the stage... I now want to do either a FullTextSQLQuery or a KeywordQuery against either the MOSS or WSS query engine and get security trimmed results based on an impersonated user. Both objects can take a SPSite on the constructor, but ignore my impersonation logic. They go with the currently logged in user instead (HTTPContext.Current.User).

There are other constructors as well: application name (string) and for MOSS there's one with a ServerContext to the SSP, but I don't think these will help at all.

I've used Reflector on the KeywordQuery class and its base Query class and it gets pretty ugly pretty quick. I believe the actual logic that determines the user is down in unmanaged code.

So, is it possible for me to do this?

like image 218
Kirk Liemohn Avatar asked Jun 22 '09 03:06

Kirk Liemohn


2 Answers

You need real Windows impersonation to do this. The SPSite impersonation is not real impersonation - it just tells the WSS object model to write another user id to the created and modified fields in the content database.

For Windows impersonation you will unfortunately need both the login and password unless you want to impersonate the application pool account using SPSecurity.RunWithElevatedPrivileges

You can implement Windows impersonation as follows:

using (Impersonator imp = new Impersonator("user", "domain", "password"))
{
  // Do stuff impersonated
}

where the Impersonator class is implemented as:

public sealed class Impersonator : IDisposable
{
  private WindowsImpersonationContext impersonationContext;

  public Impersonator(string user, string domain, string password)
  {
    WindowsIdentity id = Logon(user, domain, password);
    impersonationContext = id.Impersonate();
  }

  public void Dispose()
  {
    if (impersonationContext != null)
    {
      impersonationContext.Undo();
      impersonationContext = null;
    }
  }

  private WindowsIdentity Logon(string user, string domain, string password)
  {
    WindowsIdentity identity;
    IntPtr handle = IntPtr.Zero;
    bool logonSucceeded = LogonUser(
      user, domain, password,
      8,   // LOGON32_LOGON_NETWORK_CLEARTEXT
      0,   // LOGON32_PROVIDER_DEFAULT
      ref handle);

    if (!logonSucceeded)
    {
      int errorCode = Marshal.GetLastWin32Error();
      throw new UnauthorizedAccessException("User logon failed. Error Number: " + errorCode);
    }

    identity = new WindowsIdentity(handle);
    CloseHandle(handle);

    return identity;
  }

  [DllImport("advapi32.dll", SetLastError = true)]
  private static extern bool LogonUser(string lpszUsername,
    string lpszDomain,
    string lpszPassword,
    int dwLogonType,
    int dwLogonProvider,
    ref IntPtr phToken);

  [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
  private static extern bool CloseHandle(IntPtr handle);
}
like image 198
Lars Fastrup Avatar answered Oct 04 '22 21:10

Lars Fastrup


It turns out that you can do impersonated search in SharePoint without a password. We figured this out back in August of 2009 and I have been remiss in updating Stack Overflow with the answer.

See http://wiki.threewill.com/display/is/2010/06/18/Connect+to+SharePoint+-+Forwarding+User+Identities for the details and pay special attention to the special requirements. Note that this does work with both SharePoint 2007 and SharePoint 2010.

Many thanks to my coworker Eric Bowden who did all of the work!

like image 30
Kirk Liemohn Avatar answered Oct 04 '22 22:10

Kirk Liemohn