internal static void SetLocalAccountPassword()

in LinuxCommunicator/Credentials.cs [282:349]


        internal static void SetLocalAccountPassword(string username, SecureString newPassword, SecureString oldPassword)
        {
            IntPtr newPlainPassword = IntPtr.Zero;
            IntPtr oldPlainPassword = IntPtr.Zero;

            try
            {
                if (newPassword == null)
                {
                    newPlainPassword = Marshal.StringToCoTaskMemUni(String.Empty);
                }
                else
                {
                    newPlainPassword = Marshal.SecureStringToCoTaskMemUnicode(newPassword);
                }


                if (oldPassword == null)
                {
                    oldPlainPassword = Marshal.StringToCoTaskMemUni(String.Empty);
                }
                else
                {
                    oldPlainPassword = Marshal.SecureStringToCoTaskMemUnicode(oldPassword);
                }

                // Note: the first parameter of NetUserChangePassword is domain name. If it
                // is NULL, the logon domain of the caller, instead of local computer, is used.
                // This is unlike NetUserAdd, NetUserGetInfo or NetUserSetInfo.
                uint errCode = CredentialNativeMethods.NetUserChangePassword(
                    Environment.MachineName, username, oldPlainPassword, newPlainPassword);

                if (errCode != CredentialNativeMethods.NERR_Success)
                {
                    switch (errCode)
                    {
                        case CredentialNativeMethods.NERR_UserNotFound:
                            throw new ArgumentException("The local user " + username + " is not found.");

                        case CredentialNativeMethods.NERR_PasswordTooShort:
                            // If password is long enough but still you receive error
                            // "NERR_PasswordTooShort"  in a DOMAIN environment, then it is probably
                            // an indication that the time span since the previous password change
                            // operation is shorter than the allowed policy. It is a policy in AD to 
                            // have a minimum password age, for example, of 1 day.
                            throw new ArgumentException("The password given is too short.");

                        case CredentialNativeMethods.ERROR_INVALID_PASSWORD:
                            throw new ArgumentException("The given old password is not valid.");

                        default:
                            throw new Exception("Error when trying to reset password for local account " + username + " exists. Error code: " + errCode);
                    }
                }
            }
            finally
            {
                if (newPlainPassword != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(newPlainPassword);
                }

                if (oldPlainPassword != IntPtr.Zero)
                {
                    Marshal.ZeroFreeCoTaskMemUnicode(oldPlainPassword);
                }
            }
        }