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