Generate GPO Report From Untrusted Domain

4

I'm calling LogonUser with LOGON_TYPE_NEW_CREDENTIALS and LOGON32_PROVIDER_WINNT50 to get my thread to impersonate a user in the other domain. I'm able to connect to remote file shares and everything else just fine into the untrusted domain.

The problem I'm running into now is when I use GPMGMTLib to generate a GPO report I keep getting exception "HRESULT: 0x80072020" when it calls GenerateReport().

using GPMGMTLib;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace CrossDomainWork
{
    class Program
    {
        static void Main(string[] args)
        {
            ImpersonationContext context = new ImpersonationContext("ourdmzdomain.com", "dmzuser", "dmzpassword");
            context.Start();

            GPM gpm = new GPM();
            var constants = gpm.GetConstants();
            var domain = gpm.GetDomain("ourdmzdomain.com", "", constants.UseAnyDC);
            var gpo = domain.GetGPO("{31B2F340-016D-11D2-945F-00C04FB984F9}");
            object missing = Type.Missing;
            var result = gpo.GenerateReport(GPMReportType.repHTML, ref missing, out missing).Result;

            context.Stop();
        }
    }
}
c#
.net
active-directory
asked on Stack Overflow Apr 25, 2016 by Superdumbell

1 Answer

1

I have no experience here, so this is just a guess.

Looking at the documentation for GenerateReport, the last two parameters are pvarGPMProgress (for reporting progress), and pvarGPMCancel (some kind of cancellation token).

You are passing the same object for both. I wonder if that's what's making it choke. You can try creating a second object.

Maybe it's also possible that it doesn't like getting Type.Missing as the value. You can try just setting them to null.

Also, does the group policy have any special permissions on it?

What namespace is that ImpersonationContext in that you're using? I can't find it. We do have an untrusted domain at work that I can test with, if I can get your code to compile.

Edit: If you have SetLastError = true in your DllImport statements, then you can use Marshal.GetLastWin32Error() to get some additional details. For example:

try {
    result = gpo.GenerateReport(GPMReportType.repHTML, ref missing, out missing).Result;
} catch {
    var win32 = new Win32Exception(Marshal.GetLastWin32Error());
    Console.Write(win32.Message);
}

For me, it tells me

An attempt was made to reference a token that does not exist

Which doesn't solve the puzzle, but it's another piece to the puzzle.

answered on Stack Overflow Apr 30, 2016 by Gabriel Luci • edited May 2, 2016 by Gabriel Luci

User contributions licensed under CC BY-SA 3.0