mirror of
https://github.com/MichaelGrafnetter/DSInternals
synced 2024-12-12 01:16:31 +00:00
112 lines
4.5 KiB
C#
112 lines
4.5 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace DSInternals.Common.Data
|
|
{
|
|
/// <summary>
|
|
/// Represents a group-managed service account's password information.
|
|
/// </summary>
|
|
/// <see>https://msdn.microsoft.com/en-us/library/hh881234.aspx</see>
|
|
public class ManagedPassword
|
|
{
|
|
private const int MinimumBlobLength = 6 * sizeof(short) + sizeof(int);
|
|
|
|
/// <summary>
|
|
/// Gets the version of the msDS-ManagedPassword binary large object (BLOB).
|
|
/// </summary>
|
|
public short Version
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the current password.
|
|
/// </summary>
|
|
public string CurrentPassword
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the previous password.
|
|
/// </summary>
|
|
public string PreviousPassword
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the length of time after which the receiver should requery the password.
|
|
/// </summary>
|
|
public TimeSpan QueryPasswordInterval
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the length of time before which password queries will always return this password value.
|
|
/// </summary>
|
|
public TimeSpan UnchangedPasswordInterval
|
|
{
|
|
get;
|
|
private set;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="ManagedPassword"/> class.
|
|
/// </summary>
|
|
/// <param name="blob">
|
|
/// The MSDS-MANAGEDPASSWORD_BLOB, which is a representation
|
|
/// of a group-managed service account's password information.
|
|
/// This structure is returned as the msDS-ManagedPassword constructed attribute.
|
|
/// </param>
|
|
public ManagedPassword(byte[] blob)
|
|
{
|
|
Validator.AssertMinLength(blob, MinimumBlobLength, "blob");
|
|
using (Stream stream = new MemoryStream(blob))
|
|
{
|
|
using (BinaryReader reader = new BinaryReader(stream))
|
|
{
|
|
// A 16-bit unsigned integer that defines the version of the msDS-ManagedPassword binary large object (BLOB). The Version field MUST be set to 0x0001.
|
|
this.Version = reader.ReadInt16();
|
|
// TODO: Test that version == 1
|
|
|
|
// A 16-bit unsigned integer that MUST be set to 0x0000.
|
|
short reserved = reader.ReadInt16();
|
|
// TODO: Test that reserved == 0
|
|
|
|
// A 32-bit unsigned integer that specifies the length, in bytes, of the msDS-ManagedPassword BLOB.
|
|
int length = reader.ReadInt32();
|
|
Validator.AssertLength(blob, length, "blob");
|
|
|
|
// A 16-bit offset, in bytes, from the beginning of this structure to the CurrentPassword field. The CurrentPasswordOffset field MUST NOT be set to 0x0000.
|
|
short currentPasswordOffset = reader.ReadInt16();
|
|
this.CurrentPassword = blob.ReadWString(currentPasswordOffset);
|
|
|
|
// A 16-bit offset, in bytes, from the beginning of this structure to the PreviousPassword field. If this field is set to 0x0000, then the account has no previous password.
|
|
short previousPasswordOffset = reader.ReadInt16();
|
|
if(previousPasswordOffset > 0)
|
|
{
|
|
this.PreviousPassword = blob.ReadWString(previousPasswordOffset);
|
|
}
|
|
|
|
// A 16-bit offset, in bytes, from the beginning of this structure to the QueryPasswordInterval field.
|
|
short queryPasswordIntervalOffset = reader.ReadInt16();
|
|
long queryPasswordIntervalBinary = BitConverter.ToInt64(blob, queryPasswordIntervalOffset);
|
|
this.QueryPasswordInterval = TimeSpan.FromTicks(queryPasswordIntervalBinary);
|
|
|
|
// A 16-bit offset, in bytes, from the beginning of this structure to the UnchangedPasswordInterval field.
|
|
short unchangedPasswordIntervalOffset = reader.ReadInt16();
|
|
long unchangedPasswordIntervalBinary = BitConverter.ToInt64(blob, unchangedPasswordIntervalOffset);
|
|
this.UnchangedPasswordInterval = TimeSpan.FromTicks(unchangedPasswordIntervalBinary);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|