using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class AdvApi32
{
/// The MSChapSrvChangePassword function changes the password of a user account.
///
/// A pointer to a null-terminated Unicode string that specifies the Universal Naming Convention (UNC) name of the server on which to
/// operate. If this parameter is NULL, the function operates on the local computer.
///
///
/// A pointer to a null-terminated Unicode string that specifies the name of the user whose password is being changed.
///
///
/// A BOOLEAN that specifies whether the password designated by LmOldOwfPassword is valid. LmOldPresent is FALSE if the
/// LmOldOwfPassword password is greater than 128-bits in length, and therefore cannot be represented by a Lan Manager (LM) one-way
/// function (OWF) password. Otherwise, it is TRUE.
///
///
/// A pointer to a LM_OWF_PASSWORD structure that contains the OWF of the user's current LM password. This parameter is ignored if
/// LmOldPresent is FALSE.
///
/// A pointer to a LM_OWF_PASSWORD structure that contains the OWF of the user's new LM password.
/// A pointer to a NT_OWF_PASSWORD structure that contains the OWF of the user's current NT password.
/// A pointer to a NT_OWF_PASSWORD structure that contains the OWF of the user's new NT password.
///
/// If the function succeeds, the return value is STATUS_SUCCESS (0x00000000).
/// If the function fails, the return value is one of the following error codes from ntstatus.h.
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_ACCESS_DENIED 0xC0000022
/// The calling application does not have the appropriate privilege to complete the operation.
///
/// -
/// STATUS_INVALID_HANDLE 0xC0000008
/// The specified server or user name was not valid.
///
/// -
/// STATUS_ILL_FORMED_PASSWORD 0xC000006B
/// New password is poorly formed, for example, it contains characters that cannot be entered from the keyboard.
///
/// -
/// STATUS_PASSWORD_RESTRICTION 0xC000006C
///
/// A restriction prevents the password from being changed. Possible restrictions include time restrictions on how often a password
/// is allowed to be changed or length restrictions on the provided password. This error is also returned if the new password matched
/// a password in the recent history log for the account. Security administrators specify how many of the most recently used
/// passwords are not available for re-use. These are kept in the password recent history log.
///
///
/// -
/// STATUS_WRONG_PASSWORD 0xC000006A
/// The old password parameter does not match the user's current password.
///
/// -
/// STATUS_INVALID_DOMAIN_STATE 0xC00000DD
/// The domain controlelr is not in an enabled state. The domain controller must be enabled for this operation.
///
/// -
/// STATUS_INVALID_DOMAIN_ROLE 0xC00000DE
///
/// The domain controller is serving in the incorrect role to perform the requested operation. The operation can only be performed by
/// the primary domain controller.
///
///
/// -
/// STATUS_INVALID_PARAMETER_MIX 0xC0000030
/// The value of the LmOldPresent parameter is not correct for the contents of the old and new parameter pairs.
///
///
///
///
///
/// The value specified by LmNewOwfPassword must always contain a valid OWF. If the new password is greater than 128-bits long, and
/// therefore cannot be represented by a LAN Manager (LM) password, then LmNewOwfPassword should be the LM OWF of a NULL password.
///
/// This function allows users to change their own passwords only if they have the access: USER_CHANGE_PASSWORD.
///
/// This function fails with STATUS_PASSWORD_RESTRICTION if the attempt to change the password conflicts with an
/// administrative password restriction.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/mschapp/nf-mschapp-mschapsrvchangepassword DWORD MSChapSrvChangePassword(
// PWSTR ServerName, PWSTR UserName, BOOLEAN LmOldPresent, PLM_OWF_PASSWORD LmOldOwfPassword, PLM_OWF_PASSWORD LmNewOwfPassword,
// PNT_OWF_PASSWORD NtOldOwfPassword, PNT_OWF_PASSWORD NtNewOwfPassword );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mschapp.h", MSDNShortId = "6c154675-4c82-4305-8231-577f990eaeb1")]
public static extern NTStatus MSChapSrvChangePassword([MarshalAs(UnmanagedType.LPWStr)] string ServerName, [MarshalAs(UnmanagedType.LPWStr)] string UserName, [MarshalAs(UnmanagedType.U1)] bool LmOldPresent,
in LM_OWF_PASSWORD LmOldOwfPassword, in LM_OWF_PASSWORD LmNewOwfPassword, in LM_OWF_PASSWORD NtOldOwfPassword, in LM_OWF_PASSWORD NtNewOwfPassword);
///
/// The MSChapSrvChangePassword2 function changes the password of a user account while supporting mutual encryption.
///
///
///
/// A pointer to a null-terminated Unicode string that specifies the Universal Naming Convention (UNC) name of the server on which to
/// operate. If this parameter is NULL, the function operates on the local computer.
///
///
///
/// A pointer to a null-terminated Unicode string that specifies the name of the user whose password is being changed.
///
///
///
/// A pointer to a SAMPR_ENCRYPTED_USER_PASSWORD structure that contains the new clear text password encrypted using the current NT
/// one-way function (OWF) password hash as the encryption key.
///
///
/// Note Use the NewPasswordEncryptedWithOldNtPasswordHash() function as defined in RFC 2433, section A.11 to calculate
/// the cipher for NewPasswordEncryptedWithOldNt.
///
///
///
///
/// A pointer to an ENCRYPTED_NT_OWF_PASSWORD structure that contains the old NT OWF password hash encrypted using the new NT OWF
/// password hash as the encryption key.
///
///
///
///
/// A BOOLEAN that specifies if the current Lan Manager (LM) or NT OWF password hashes are used as the encryption keys to
/// generate the NewPasswordEncryptedWithOldNt and OldNtOwfPasswordEncryptedWithNewNt ciphers. If TRUE, the LM OWF password
/// hashes are used rather than the NT OWF password hashes.
///
///
///
///
/// A pointer to a SAMPR_ENCRYPTED_USER_PASSWORD structure that contains the new clear text password encrypted using the current LM
/// OWF password hash.
///
///
/// Note Use the NewPasswordEncryptedWithOldLmPasswordHash() function as defined in RFC 2433, section A.15 to calculate
/// the cipher for NewPasswordEncryptedWithOldLm.
///
///
///
///
/// A pointer to a ENCRYPTED_LM_OWF_PASSWORD structure that contains the current LM OWF password hash encrypted using the new LM OWF
/// password hash.
///
///
///
/// If the function succeeds, the return value is STATUS_SUCCESS (0x00000000).
/// If the function fails, the return value is one of the following error codes from ntstatus.h.
///
///
/// Return code/value
/// Description
///
/// -
/// STATUS_ACCESS_DENIED 0xC0000022
/// The calling application does not have the appropriate privilege to complete the operation.
///
/// -
/// STATUS_INVALID_HANDLE 0xC0000008
/// The specified server or user name was not valid.
///
/// -
/// STATUS_ILL_FORMED_PASSWORD 0xC000006B
/// New password is poorly formed, for example, it contains characters that cannot be entered from the keyboard.
///
/// -
/// STATUS_PASSWORD_RESTRICTION 0xC000006C
///
/// A restriction prevents the password from being changed. Possible restrictions include time restrictions on how often a password
/// is allowed to be changed or length restrictions on the provided password. This error is also returned if the new password matched
/// a password in the recent history log for the account. Security administrators specify how many of the most recently used
/// passwords are not available for re-use. These are kept in the password recent history log.
///
///
/// -
/// STATUS_WRONG_PASSWORD 0xC000006A
/// The old password parameter does not match the user's current password.
///
/// -
/// STATUS_INVALID_DOMAIN_STATE 0xC00000DD
/// The domain controller is not in an enabled state. The domain controller must be enabled for this operation.
///
/// -
/// STATUS_INVALID_DOMAIN_ROLE 0xC00000DE
///
/// The domain controller is serving in the incorrect role to perform the requested operation. The operation can only be performed by
/// the primary domain controller.
///
///
///
///
///
/// This function allows users to change their own passwords only if they have the access: USER_CHANGE_PASSWORD.
///
/// This function fails with STATUS_PASSWORD_RESTRICTION if the attempt to change the password conflicts with an
/// administrative password restriction.
///
///
// https://docs.microsoft.com/en-us/windows/desktop/api/mschapp/nf-mschapp-mschapsrvchangepassword2 DWORD MSChapSrvChangePassword2(
// PWSTR ServerName, PWSTR UserName, PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt, PENCRYPTED_NT_OWF_PASSWORD
// OldNtOwfPasswordEncryptedWithNewNt, BOOLEAN LmPresent, PSAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm,
// PENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewLmOrNt );
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mschapp.h", MSDNShortId = "91ea4b98-79e4-4764-a580-a622d1491943")]
public static extern NTStatus MSChapSrvChangePassword2([MarshalAs(UnmanagedType.LPWStr)] string ServerName, [MarshalAs(UnmanagedType.LPWStr)] string UserName, in SAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt,
in ENCRYPTED_LM_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt, [MarshalAs(UnmanagedType.U1)] bool LmPresent, in SAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm, in ENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewLmOrNt);
/// The CYPHER_BLOCK is the basic unit of storage for the one-way function (OWF) password hashes.
// https://docs.microsoft.com/en-us/windows/desktop/api/mschapp/ns-mschapp-cypher_block typedef struct _CYPHER_BLOCK { CHAR
// data[CYPHER_BLOCK_LENGTH]; } CYPHER_BLOCK;
[PInvokeData("mschapp.h", MSDNShortId = "eb0e38ed-8d12-4df2-be58-7ac18447121f")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CYPHER_BLOCK
{
///
/// An array of CHAR used to store the password hashes and cipher text passed by the MS-CHAP password management API.
///
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] data;
}
///
/// The ENCRYPTED_LM_OWF_PASSWORD stores a user's encrypted Lan Manager (LM) one-way function (OWF) password hash.
///
/// ENCRYPTED_NT_OWF_PASSWORD is an alias for this structure.
// https://docs.microsoft.com/en-us/windows/desktop/api/mschapp/ns-mschapp-_encrypted_lm_owf_password typedef struct
// _ENCRYPTED_LM_OWF_PASSWORD { CYPHER_BLOCK data[2]; } ENCRYPTED_LM_OWF_PASSWORD, *PENCRYPTED_LM_OWF_PASSWORD;
[PInvokeData("mschapp.h", MSDNShortId = "83498d3f-0ac5-435c-804e-a4baa1ae855d")]
public struct ENCRYPTED_LM_OWF_PASSWORD
{
///
/// An array of CYPHER_BLOCK structures that contain an encrypted LM OWF password hash. The contents of the array are calculated
/// using the OldLmPasswordHashEncryptedWithNewNtPasswordHash() function as defined in RFC 2433, section A.16.
///
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public CYPHER_BLOCK[] data;
}
/// The LM_OWF_PASSWORD stores the Lan Manage (LM) one-way function (OWF) of a user's password.
/// NT_OWF_PASSWORD is an alias for this structure.
// https://docs.microsoft.com/en-us/windows/desktop/api/mschapp/ns-mschapp-_lm_owf_password typedef struct _LM_OWF_PASSWORD {
// CYPHER_BLOCK data[2]; } LM_OWF_PASSWORD;
[PInvokeData("mschapp.h", MSDNShortId = "db155f34-fa57-4449-9319-d46561fd18c0")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct LM_OWF_PASSWORD
{
///
/// An array of CYPHER_BLOCK structures that contain a LM OWF password hash. The contents of the array are calculated using the
/// LmEncryptedPasswordHash() function as defined in RFC 2433, section A.8.
///
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public CYPHER_BLOCK[] data;
}
/// The SAMPR_ENCRYPTED_USER_PASSWORD stores a user's encrypted password.
// https://docs.microsoft.com/en-us/windows/desktop/api/mschapp/ns-mschapp-_sampr_encrypted_user_password typedef struct
// _SAMPR_ENCRYPTED_USER_PASSWORD { UCHAR *Buffer[(256 2)+ 4]; } SAMPR_ENCRYPTED_USER_PASSWORD, *PSAMPR_ENCRYPTED_USER_PASSWORD;
[PInvokeData("mschapp.h", MSDNShortId = "10137c59-db99-4d70-9716-6f05369084a0")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SAMPR_ENCRYPTED_USER_PASSWORD
{
///
/// An array contains an encrypted password. The contents of the array are calculated using either the
/// NewPasswordEncryptedWithOldNtPasswordHash or NewPasswordEncryptedWithOldLmPasswordHash functions as defined in
/// RFC 2433, sections A.11 and A.15 respectively.
///
[MarshalAs(UnmanagedType.ByValArray, SizeConst = (256 * 2) + 4)]
public byte[] Buffer;
}
}
}