views:

430

answers:

1

I am trying to call NetUserChangePassword to change the passwords on a remote computer. I am able to change the password when I log-in to the machine, but I can't do it via code. The return value is 2245 which equates to the Password Being too short.

I read this link: http://support.microsoft.com/default.aspx?scid=kb;en-us;131226 but nothing in the link was helpful to me. (My code did not seem to fit any of the issues indicated.)

If you have any ideas how to fix this error or have a different way to programmatically change a users password on a remote (Windows 2003) machine I would be grateful to hear it.

I am running the code on a windows xp machine.

Here is my current code in-case it is helpful (Also shows my create user code which works just fine).

public partial class Form1 : Form
{
    [DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    private static extern int NetUserAdd(
         [MarshalAs(UnmanagedType.LPWStr)] string servername,
         UInt32 level,
         ref USER_INFO_1 userinfo,
         out UInt32 parm_err);

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct USER_INFO_1
    {
        [MarshalAs(UnmanagedType.LPWStr)]
        public string sUsername;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string sPassword;
        public uint uiPasswordAge;
        public uint uiPriv;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string sHome_Dir;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string sComment;
        public uint uiFlags;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string sScript_Path;
    }

    [DllImport("netapi32.dll", CharSet = CharSet.Unicode, 
        CallingConvention = CallingConvention.StdCall, SetLastError = true)]
    static extern uint NetUserChangePassword(
        [MarshalAs(UnmanagedType.LPWStr)] string domainname,
        [MarshalAs(UnmanagedType.LPWStr)] string username,
        [MarshalAs(UnmanagedType.LPWStr)] string oldpassword,
        [MarshalAs(UnmanagedType.LPWStr)] string newpassword);

    // Method to change a Password of a user on a remote machine.
    private static uint ChangeUserPassword(string computer, string userName,
        string oldPassword, string newPassword)
    {
        return NetUserChangePassword(computer, userName, 
            oldPassword, newPassword);
    }


    // Method used to create a new user on a Remote Machine
    private static uint CreateUser(string computer, string userName, 
        string password)
    {
        const int UF_DONT_EXPIRE_PASSWD = 0x10000;
        const int UF_ACCOUNTDISABLE = 0x000002;

        const int USER_PRIV_GUEST = 0; // lmaccess.h:656
        const int USER_PRIV_USER = 1;   // lmaccess.h:657
        const int USER_PRIV_ADMIN = 2;  // lmaccess.h:658

        USER_INFO_1 userinfo = new USER_INFO_1()
        {
            sComment = "Scan Track User",
            sUsername = userName,
            sPassword = password,
            sHome_Dir = "",
            sScript_Path = "",
            uiPriv = USER_PRIV_USER,
            uiFlags = UF_DONT_EXPIRE_PASSWD
        };


        uint output;
        NetUserAdd(computer, 1, ref userinfo, out output);
        return output;
    }

    private void button1_Click(object sender, EventArgs e)
    {

        string computer = "10.1.9.115";
        string userName = "test2";
        string psswrd = "ssssss";
        string fullname = "";

        uint output = CreateUser(computer, userName, psswrd);
        MessageBox.Show(output.ToString());
    }


    private void button2_Click(object sender, EventArgs e)
    {
        string computer = "10.1.9.115";
        string userName = "test";
        string oldPassword = "!B3tt3rLuck!@!";
        string newPassword = "!B3tt3r-Luck2";

        uint result = ChangeUserPassword(computer, userName, 
            oldPassword, newPassword);

        MessageBox.Show(result.ToString());
    }


    public Form1()
    {
        InitializeComponent();
    }


}
+1  A: 

Error 2245 could also be a password history problem. Is the new password one that was used in the recent past?

Edit: It looks like this function broke after Server 2003 SP 2. I got the same error when calling the function from C++ using the example in the documentation. You'll probably need to use NetUserSetInfo.

Adam Ruth
I thought that might be it too. I changed it to something that was completely unique and it still failed. (thanks for the idea though).
Vaccano