Нужен способ изменить пароль удаленного пользователя - NetUserChangePassword не работает с 2245

Я пытаюсь позвонить NetUserChangePassword изменить пароли на удаленном компьютере. Я могу сменить пароль при входе в систему, но не могу сделать это с помощью кода. Возвращаемое значение - 2245, что соответствует слишком короткому паролю.

Я прочитал эту ссылку: http://support.microsoft.com/default.aspx?scid=kb;en-us;131226 но ничего в этой ссылке мне не помогло. (Мой код не соответствует ни одной из указанных проблем.)

Если у вас есть идеи, как исправить эту ошибку, или у вас есть другой способ программно изменить пароль пользователя на удаленном компьютере (Windows 2003), я был бы рад услышать его.

Я бегу код на машине Windows XP.

Вот мой текущий код в случае, если он полезен (также показывает мой пользовательский код создания, который работает просто отлично).

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();
    }


}

3 ответа

Решение

Ошибка 2245 также может быть проблемой истории паролей. Является ли новый пароль тем, который использовался в недавнем прошлом?

Редактировать: похоже, что эта функция сломалась после Server 2003 SP 2. Я получил ту же ошибку при вызове функции из C++, используя пример в документации. Вы, вероятно, должны будете использовать NetUserSetInfo.

Я был озадачен той же самой проблемой во время первоначальной разработки и тестирования, пока не обнаружил недокументированное ограничение этого API - пароль, который вы пытаетесь изменить, ДОЛЖЕН БЫТЬ ДЕЙСТВИТЕЛЬНО БЫТЬ СРОЧЕН, чтобы изменение прошло успешно!

На моей установке Windows 2008 R2 мне пришлось изменить 2 GPO, чтобы сделать NetUserChangePassword Работа.

Мне пришлось установить (через объект групповой политики) "минимальный срок действия пароля" на 0, так как я только что создал тестовую учетную запись, и все попытки до этого изменения привели к коду "пароль слишком короткий".

Поскольку моя виртуальная машина является DC, я должен был разрешить своим тестовым пользователям входить в DC, чтобы метод работал.

Другие вопросы по тегам