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

Я пытаюсь позвонить 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 ]

3 голосов
/ 06 сентября 2012

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

1 голос
/ 16 июля 2009

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

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

0 голосов
/ 15 августа 2013

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

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

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

...