Exception while impersonating

Aug 21, 2009 at 8:47 PM

Hi,

I'm using the AlphaVSS libraries in conjunction with Windows Impersonation in a C# application.  My normal user is part of the admin group, and so is the user I'm impersonating. The two users have, as nearly as I can tell, identical permissions.  When I run my application without impersonating everything works beautifully.  However, when I insert the call to impersonate I get a Unexpected System Exception when I call CreateVssBackupComponents().  It also inserts an entry into my Windows Event Viewer's Application log:

Volume Shadow Copy Service error: Unexpected error calling routine OpenProcessToken.  hr = 0x80070005.

I've been scratching my head over this for a couple of days to no avail and I really need to get this done so any help would be greatly appreciated.  I'm at a loss at this point.


TIA!

Coordinator
Aug 23, 2009 at 7:14 AM

Unfortunately I have no idea what might be going on here without more information, preferrably stepping through the library using a debugger trying to figure out exactly what is going wrong. 

I never tried it using impersonation. Perhaps you could supply a minimal sample code that produces this error?

 

Aug 24, 2009 at 1:54 PM
Edited Aug 24, 2009 at 2:00 PM

This short sample program exhibits the problem, at least on my computer.  Let me know if you have any questions, and thanks in advance for the help, I'm really stuck on this one.  Comment out the changeToBackupUser() call and the VSS code works fine.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using System.IO;
using System.Collections;
using Alphaleonis.Win32.Vss;

namespace VssImpersonationFail {
    class Program {
        // Constants for the impersonation code
        private const int LOGON_TYPE_INTERACTIVE = 2;
        private const int LOGON_TYPE_PROVIDER_DEFAULT = 0;

        // Api to get an accessToken of specific Windows User by username and password
        [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        static public extern bool LogonUser(string userName, string domain, string passWord, int logonType, int logonProvider, ref IntPtr accessToken);

        [DllImport("kernel32.dll")]
        public extern static bool CloseHandle(IntPtr hToken);

        // Other variables having to do with the impersonation code
        WindowsIdentity identity = null;
        WindowsImpersonationContext context = null;

        private string domain = "DOMAIN_OR_MACHINE_NAME";
        private string userName = "ADMIN_USER_NAME";
        private string password = "PASSWORD";

        private void changeToBackupUser() {
            IntPtr accessToken = IntPtr.Zero;

            try {
                if(LogonUser(userName, domain, password, LOGON_TYPE_INTERACTIVE, LOGON_TYPE_PROVIDER_DEFAULT, ref accessToken)) {
                    identity = new WindowsIdentity(accessToken);
                    context = identity.Impersonate();
                    CloseHandle(accessToken); // Free the handle

                    Console.WriteLine(WindowsIdentity.GetCurrent().Name);
                }
                else {
                    int ret = Marshal.GetLastWin32Error();
                    throw new System.ComponentModel.Win32Exception(ret);
                }
            }
            catch(Exception ex) {
                Console.WriteLine(ex.Message);
            }
        }

        private void changeToNormalUser() {
            if(context != null)
                context.Undo();

            Console.WriteLine(WindowsIdentity.GetCurrent().Name);
        }

        private void vssCopy() {
            IVssImplementation vss = VssUtils.LoadImplementation();
            IVssBackupComponents backup = vss.CreateVssBackupComponents();
            backup.InitializeForBackup(null);
            using(IVssAsync async = backup.GatherWriterMetadata()) {
                async.Wait();
            }
        }

        public void runTest() {
changeToBackupUser(); vssCopy(); changeToNormalUser(); } static void Main(string[] args) { Program p = new Program(); p.runTest(); } } }

 

 

Coordinator
Aug 24, 2009 at 3:45 PM

Hi, and thanks for providing a full code-example, makes things so much easier.

However, unfortunately, in this case the program runs quite nicely on my computer if both users are part of the local administrators group.

This is on a Windows 7 x64 machine that is not part of a domain.  What setup are you running the application on?

 

Aug 24, 2009 at 3:51 PM

I hate it when that happens! :-)

I'm running on Windows XP SP2, 32 bit.  I am in a domain, but the same thing happens whether I use the local machine admin user or a domain user that's added to the admin group.  Also, I'm compiling using .NET 2.0 and VS2005, not sure if that would make a difference.  I wonder if domain policy is causing the problem somehow?

Thanks!

 

Aug 26, 2009 at 2:18 PM

I've tried this same code on 3 different computers now.  2 with XP SP2 on a domain, one with XP SP3 *not* on a domain.  I had the same results in all cases.  Is this perhaps an XP issue?

I've tried to debug the libraries to see if I was able to pin down more accurately what was happening.  For some reason I'm unable to get my version of Visual Studio to load the debug versions of the libraries so I've had to rely just on using the source code. I'm not sure how much difference that makes.  At any rate, the problem ultimately occurs at line 53 of vssbackupcomponents.cpp, in the VssBackupComponents constructor:

CheckCom( CreateVssBackupComponents(pVssObject) );

I am unable to step into the CreateVssBackupComponents(pVssObject) call for some reason, and I have not been able to find that particular method call (one that accepts an argument) in the source.  When this call executes pVssObject is null, which I suspect is the problem.  The error passed to the CheckCom macro is -2147418113 if that helps at all. 

Any suggestions at this point would be greatly appreciated!

Thanks again

Coordinator
Aug 26, 2009 at 3:58 PM

Hi again..

I suspect this might be an XP-issue, although I am not sure exactly what's causing it. But VSS support in XP is somewhat limited as you may know. I just finished re-installing XP on a VMWare since it had dissapeared for some reason so I'm planning to try it there and see what happens.

The reason you can't step into CreateVssBackupComponents is because it's a Win32 API function ;)

But I'll let you know as soon as I come up with any results.