views:

38

answers:

0

This question is third on a series. Thanks to Gonzalo and Mattias S for helping me work out the kinks of calling NetUserModalsGet() from C#. This question, unlike the others, isn't really C# specific -- I think.

Here's the working code with which I can call NetUserModalsGet() from C# on a remote machine. It works well, but according to the documentation usrmod1_primary and usrmod2_domain_name should give me the address of the domain controller, and the name of the domain the machine is a member of.

Instead, I get a blank string for usrmod1_primary and the machine name for usrmod2_domain_name -- it's as if the machine isn't in a domain. Am I looking for information in the wrong place?

[DllImport("netapi32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern uint NetUserModalsGet(
    string server,
    int level,
    out IntPtr BufPtr
);

[DllImport("netapi32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
public static extern uint NetApiBufferFree(
    IntPtr bufptr
);

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct USER_MODALS_INFO_0
{
    public uint usrmod0_min_passwd_len;
    public uint usrmod0_max_passwd_age;
    public uint usrmod0_min_passwd_age;
    public uint usrmod0_force_logoff;
    public uint usrmod0_password_hist_len;
};

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct USER_MODALS_INFO_1
{
    public uint usrmod1_role;
    public string usrmod1_primary;
};

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct USER_MODALS_INFO_2
{
    public string usrmod2_domain_name;
    public IntPtr usrmod2_domain_id;
};

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
public struct USER_MODALS_INFO_3
{
    public uint usrmod3_lockout_duration;
    public uint usrmod3_lockout_observation_window;
    public uint usrmod3_lockout_threshold;
};

...

uint retVal;
IntPtr myBuf;
USER_MODALS_INFO_0 myInfo0 = new USER_MODALS_INFO_0();
USER_MODALS_INFO_1 myInfo1 = new USER_MODALS_INFO_1();
USER_MODALS_INFO_2 myInfo2 = new USER_MODALS_INFO_2();
USER_MODALS_INFO_3 myInfo3 = new USER_MODALS_INFO_3();

retVal = NetUserModalsGet("\\\\" + tbHost.Text, 0, out myBuf);
if (retVal == 0)
{
    myInfo0 = (USER_MODALS_INFO_0)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_0));
    myResults += String.Format("usrmod0_force_logoff={0}\nusrmod0_max_passwd_age={1}\nusrmod0_min_passwd_age={2}\nusrmod0_min_passwd_len={3}\nusrmod0_password_hist_len={4}\n",
        myInfo0.usrmod0_force_logoff.ToString("X8"),
        myInfo0.usrmod0_max_passwd_age.ToString("X8"),
        myInfo0.usrmod0_min_passwd_age.ToString("X8"),
        myInfo0.usrmod0_min_passwd_len.ToString("X8"),
        myInfo0.usrmod0_password_hist_len.ToString("X8")
        );
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);

retVal = NetUserModalsGet("\\\\" + tbHost.Text, 1, out myBuf);
if (retVal == 0)
{
    myInfo1 = (USER_MODALS_INFO_1)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_1));
    myResults += String.Format("usrmod1_primary={0}\nusrmod1_role={1}\n",
        myInfo1.usrmod1_primary,
        myInfo1.usrmod1_role.ToString("X8")
        );
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);

retVal = NetUserModalsGet("\\\\" + tbHost.Text, 2, out myBuf);
if (retVal == 0)
{
    myInfo2 = (USER_MODALS_INFO_2)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_2));
    myResults += String.Format("usrmod2_domain_id={0}\nusrmod2_domain_name={1}\n",
        myInfo2.usrmod2_domain_id.ToString("X8"),
        myInfo2.usrmod2_domain_name
        );
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);

retVal = NetUserModalsGet("\\\\" + tbHost.Text, 3, out myBuf);
if (retVal == 0)
{
    myInfo3 = (USER_MODALS_INFO_3)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_3));
    myResults += String.Format("usrmod3_lockout_duration={0}\nusrmod3_lockout_observation_window={1}\nusrmod3_lockout_threshold={2}\n",
        myInfo3.usrmod3_lockout_duration.ToString("X8"),
        myInfo3.usrmod3_lockout_observation_window.ToString("X8"),
        myInfo3.usrmod3_lockout_threshold.ToString("X8")
        );
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);