diff --git a/PInvoke/Security/AdvApi32/WinNT.cs b/PInvoke/Security/AdvApi32/WinNT.cs
index 82fcaa0f..e94fa558 100644
--- a/PInvoke/Security/AdvApi32/WinNT.cs
+++ b/PInvoke/Security/AdvApi32/WinNT.cs
@@ -14,6 +14,9 @@ namespace Vanara.PInvoke
{
public const uint SECURITY_DESCRIPTOR_REVISION = 1;
public const uint SECURITY_DESCRIPTOR_REVISION1 = 1;
+ public const int SID_MAX_SUB_AUTHORITIES = 15;
+ public const int SID_RECOMMENDED_SUB_AUTHORITIES = 1; // Will change to around 6
+ public const uint SID_REVISION = 1; // Current revision level
/// Indicates whether the ObjectTypeName and InheritedObjectTypeName members contain strings.
[PInvokeData("winnt.h")]
diff --git a/PInvoke/Security/Secur32/NTSecApi.cs b/PInvoke/Security/Secur32/NTSecApi.cs
index 60c6b830..6af6f1ce 100644
--- a/PInvoke/Security/Secur32/NTSecApi.cs
+++ b/PInvoke/Security/Secur32/NTSecApi.cs
@@ -1,5 +1,8 @@
using System;
+using System.Collections.Generic;
using System.Runtime.InteropServices;
+using Vanara.Extensions;
+using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
@@ -8,6 +11,10 @@ namespace Vanara.PInvoke
/// Functions, enumerations and structures found in Secur32.dll.
public static partial class Secur32
{
+ /// Microsoft CredSSP Security Provider.
+ [PInvokeData("credssp.h")]
+ public const string CREDSSP_NAME = "CREDSSP";
+
/// The Kerberos authentication package name.
[PInvokeData("Ntsecapi.h")]
public const string MICROSOFT_KERBEROS_NAME = "Kerberos";
@@ -24,22 +31,17 @@ namespace Vanara.PInvoke
[PInvokeData("Security.h")]
public const string NTLMSP_NAME = "NTLM";
- /// Digest Authentication for Windows.
- [PInvokeData("wdigest.h")]
- public const string WDIGEST_SP_NAME = "WDigest";
-
- /// Microsoft CredSSP Security Provider.
- [PInvokeData("credssp.h")]
- public const string CREDSSP_NAME = "CREDSSP";
+ /// TS Service Security Package
+ [PInvokeData("Ntsecapi.h")]
+ public const string PKU2U_PACKAGE_NAME = "pku2u";
/// TS Service Security Package
[PInvokeData("credssp.h")]
public const string TS_SSP_NAME = "TSSSP";
- /// TS Service Security Package
- [PInvokeData("Ntsecapi.h")]
- public const string PKU2U_PACKAGE_NAME = "pku2u";
-
+ /// Digest Authentication for Windows.
+ [PInvokeData("wdigest.h")]
+ public const string WDIGEST_SP_NAME = "WDigest";
/// Kerberos encryption types.
[PInvokeData("Ntsecapi.h", MSDNShortId = "3b088c94-810b-44c7-887a-58e8dbd13603")]
public enum KERB_ETYPE
@@ -85,6 +87,40 @@ namespace Vanara.PInvoke
KERB_ETYPE_RC4_HMAC_NT_EXP = 24
}
+ /// The KERB_LOGON_SUBMIT_TYPE enumeration identifies the type of logon being requested.
+ // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ne-ntsecapi-kerb_logon_submit_type
+ // typedef enum _KERB_LOGON_SUBMIT_TYPE { KerbInteractiveLogon, KerbSmartCardLogon, KerbWorkstationUnlockLogon, KerbSmartCardUnlockLogon, KerbProxyLogon, KerbTicketLogon, KerbTicketUnlockLogon, KerbS4ULogon, KerbCertificateLogon, KerbCertificateS4ULogon, KerbCertificateUnlockLogon, KerbNoElevationLogon, KerbLuidLogon } KERB_LOGON_SUBMIT_TYPE, *PKERB_LOGON_SUBMIT_TYPE;
+ [PInvokeData("ntsecapi.h", MSDNShortId = "500bee53-638b-4782-b42d-1df158396fb6")]
+ public enum KERB_LOGON_SUBMIT_TYPE
+ {
+ /// Perform an interactive logon.
+ KerbInteractiveLogon = 2,
+ /// Logon using a smart card.
+ KerbSmartCardLogon = 6,
+ /// Unlock a workstation.
+ KerbWorkstationUnlockLogon,
+ /// Unlock a workstation using a smart card.
+ KerbSmartCardUnlockLogon,
+ /// Logon using a proxy server.
+ KerbProxyLogon,
+ /// Logon using a valid Kerberos ticket as a credential.
+ KerbTicketLogon,
+ /// Unlock a workstation by using a Kerberos ticket.
+ KerbTicketUnlockLogon,
+ /// Perform a service for user logon.
+ KerbS4ULogon,
+ /// Logon interactively using a certificate stored on a smart card.
+ KerbCertificateLogon,
+ /// Perform a service for user logon using a certificate stored on a smart card.
+ KerbCertificateS4ULogon,
+ /// Unlock a workstation using a certificate stored on a smart card.
+ KerbCertificateUnlockLogon,
+ ///
+ KerbNoElevationLogon = 83,
+ ///
+ KerbLuidLogon,
+ }
+
///
///
/// The KERB_PROTOCOL_MESSAGE_TYPE enumeration lists the types of messages that can be sent to the Kerberos authentication
@@ -242,38 +278,77 @@ namespace Vanara.PInvoke
KerbQueryS4U2ProxyCacheMessage,
}
- /// The KERB_LOGON_SUBMIT_TYPE enumeration identifies the type of logon being requested.
- // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ne-ntsecapi-kerb_logon_submit_type
- // typedef enum _KERB_LOGON_SUBMIT_TYPE { KerbInteractiveLogon, KerbSmartCardLogon, KerbWorkstationUnlockLogon, KerbSmartCardUnlockLogon, KerbProxyLogon, KerbTicketLogon, KerbTicketUnlockLogon, KerbS4ULogon, KerbCertificateLogon, KerbCertificateS4ULogon, KerbCertificateUnlockLogon, KerbNoElevationLogon, KerbLuidLogon } KERB_LOGON_SUBMIT_TYPE, *PKERB_LOGON_SUBMIT_TYPE;
- [PInvokeData("ntsecapi.h", MSDNShortId = "500bee53-638b-4782-b42d-1df158396fb6")]
- public enum KERB_LOGON_SUBMIT_TYPE
+ /// Ticket flags, as defined in Internet RFC 4120. This parameter can be one or more of the following values.
+ [PInvokeData("ntsecapi.h", MSDNShortId = "742e2795-ec74-4856-a680-7a1c233a2934")]
+ [Flags]
+ public enum KERB_TICKET_FLAGS : uint
{
- /// Perform an interactive logon.
- KerbInteractiveLogon = 2,
- /// Logon using a smart card.
- KerbSmartCardLogon = 6,
- /// Unlock a workstation.
- KerbWorkstationUnlockLogon,
- /// Unlock a workstation using a smart card.
- KerbSmartCardUnlockLogon,
- /// Logon using a proxy server.
- KerbProxyLogon,
- /// Logon using a valid Kerberos ticket as a credential.
- KerbTicketLogon,
- /// Unlock a workstation by using a Kerberos ticket.
- KerbTicketUnlockLogon,
- /// Perform a service for user logon.
- KerbS4ULogon,
- /// Logon interactively using a certificate stored on a smart card.
- KerbCertificateLogon,
- /// Perform a service for user logon using a certificate stored on a smart card.
- KerbCertificateS4ULogon,
- /// Unlock a workstation using a certificate stored on a smart card.
- KerbCertificateUnlockLogon,
- ///
- KerbNoElevationLogon = 83,
- ///
- KerbLuidLogon,
+ ///
+ /// The ticket-granting server can issue a new ticket-granting ticket with a different network address, based on the presented ticket.
+ ///
+ KERB_TICKET_FLAGS_forwardable = 0x40000000,
+
+ ///
+ /// The ticket has either been forwarded or was issued based on authentication that involved a forwarded ticket-granting ticket.
+ ///
+ KERB_TICKET_FLAGS_forwarded = 0x20000000,
+
+ ///
+ /// The protocol employed for initial authentication required the use of hardware expected to be possessed solely by the named
+ /// client. The hardware authentication method is selected by the KDC, and the strength of the method is not indicated.
+ ///
+ KERB_TICKET_FLAGS_hw_authent = 0x00100000,
+
+ ///
+ /// The ticket was issued by using the Authentication Service protocol instead of being based on a ticket-granting ticket.
+ ///
+ KERB_TICKET_FLAGS_initial = 0x00400000,
+
+ /// The ticket is not valid.
+ KERB_TICKET_FLAGS_invalid = 0x01000000,
+
+ ///
+ /// Indicates to the ticket-granting server that a postdated ticket can be issued based on this ticket-granting ticket.
+ ///
+ KERB_TICKET_FLAGS_may_postdate = 0x04000000,
+
+ ///
+ /// The target of the ticket is trusted by the directory service for delegation. Thus, the clients may delegate their
+ /// credentials to the server, which lets the server act as the client when talking to other services.
+ ///
+ KERB_TICKET_FLAGS_ok_as_delegate = 0x00040000,
+
+ ///
+ /// The ticket has been postdated. The end service can check the ticket's authtime member to determine when the original
+ /// authentication occurred.
+ ///
+ KERB_TICKET_FLAGS_postdated = 0x02000000,
+
+ ///
+ /// During initial authentication, the client was authenticated by the KDC before a ticket was issued. The strength of the
+ /// preauthentication method is not indicated but is acceptable to the KDC.
+ ///
+ KERB_TICKET_FLAGS_pre_authent = 0x00200000,
+
+ ///
+ /// Indicates to the ticket-granting server that only nonticket-granting tickets can be issued with different network addresses.
+ ///
+ KERB_TICKET_FLAGS_proxiable = 0x10000000,
+
+ /// The ticket is a proxy.
+ KERB_TICKET_FLAGS_proxy = 0x08000000,
+
+ ///
+ /// The ticket is renewable. If this flag is set, the time limit for renewing the ticket is set in the RenewTime member of a
+ /// KERB_TICKET_CACHE_INFO structure. A renewable ticket can be used to obtain a replacement ticket that expires at a later date.
+ ///
+ KERB_TICKET_FLAGS_renewable = 0x00800000,
+
+ /// Reserved for future use. Do not set this flag.
+ KERB_TICKET_FLAGS_reserved = 0x80000000,
+
+ /// Reserved.
+ KERB_TICKET_FLAGS_reserved1 = 0x00000001,
}
[PInvokeData("ntsecapi.h", MSDNShortId = "8ed37546-6443-4010-a078-4359dd1c2861")]
@@ -1646,8 +1721,16 @@ namespace Vanara.PInvoke
[FieldOffset(8)]
public IntPtr Names;
- // /// public override string ToString() => NameCount == 0 ? "" : string.Join("; ",
- // Array.ConvertAll(Names.ToArray(NameCount), s => s.ToString()));
+ /// Extracts the names from .
+ /// A sequence of names.
+ public IEnumerable GetNames()
+ {
+ if (NameCount == 0)
+ yield break;
+ using var pin = new PinnedObject(this);
+ foreach (var us in ((IntPtr)pin).ToIEnum(NameCount, 8))
+ yield return us.ToString();
+ }
}
///
@@ -1785,7 +1868,7 @@ namespace Vanara.PInvoke
///
///
///
- public uint TicketFlags;
+ public KERB_TICKET_FLAGS TicketFlags;
/// Reserved for future use. Set this member to zero.
public uint Flags;
@@ -1849,6 +1932,105 @@ namespace Vanara.PInvoke
public LSA_UNICODE_STRING Password;
}
+ ///
+ /// The KERB_PURGE_TKT_CACHE_REQUEST structure contains information used to delete entries from the ticket cache.
+ /// It is used by LsaCallAuthenticationPackage.
+ ///
+ ///
+ ///
+ /// If both ServerName and RealmName are of zero length, LsaCallAuthenticationPackage will delete all tickets for the
+ /// logon session identified by LogonId. Otherwise, LsaCallAuthenticationPackage will search the cache tickets for
+ /// ServerName@ RealmName, and will delete all such tickets.
+ ///
+ ///
+ /// LsaCallAuthenticationPackage does not return this buffer. It returns STATUS_SUCCESS if one or more tickets are deleted. If no
+ /// tickets are found, the function returns SEC_E_NO_CREDENTIALS.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_purge_tkt_cache_request typedef struct
+ // _KERB_PURGE_TKT_CACHE_REQUEST { KERB_PROTOCOL_MESSAGE_TYPE MessageType; LUID LogonId; UNICODE_STRING ServerName; UNICODE_STRING
+ // RealmName; } KERB_PURGE_TKT_CACHE_REQUEST, *PKERB_PURGE_TKT_CACHE_REQUEST;
+ [PInvokeData("ntsecapi.h", MSDNShortId = "4e5e944a-8163-42de-b534-3b0478d9f334")]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct KERB_PURGE_TKT_CACHE_REQUEST
+ {
+ /// KERB_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to KerbPurgeTicketCacheMessage.
+ public KERB_PROTOCOL_MESSAGE_TYPE MessageType;
+
+ ///
+ /// LUID structure containing the logon session identifier. This can be zero for the current user's logon session. If not zero,
+ /// the caller must have the SeTcbPrivilege privilege set. If this fails, the Kerberos authentication package sets the
+ /// ProtocolStatus parameter of LsaCallAuthenticationPackage to STATUS_ACCESS_DENIED.
+ ///
+ public LUID LogonId;
+
+ /// UNICODE_STRING containing the name of the service whose tickets should be deleted from the cache.
+ public LSA_UNICODE_STRING ServerName;
+
+ /// UNICODE_STRING containing the name of the realm whose tickets should be deleted from the cache.
+ public LSA_UNICODE_STRING RealmName;
+ }
+
+ ///
+ /// The KERB_QUERY_TKT_CACHE_REQUEST structure contains information used to query the ticket cache.
+ /// It is used by LsaCallAuthenticationPackage.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_query_tkt_cache_request typedef struct
+ // _KERB_QUERY_TKT_CACHE_REQUEST { KERB_PROTOCOL_MESSAGE_TYPE MessageType; LUID LogonId; } KERB_QUERY_TKT_CACHE_REQUEST, *PKERB_QUERY_TKT_CACHE_REQUEST;
+ [PInvokeData("ntsecapi.h", MSDNShortId = "3c8e63b3-9ac4-4228-87e1-6802c3d12d6c")]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct KERB_QUERY_TKT_CACHE_REQUEST
+ {
+ ///
+ ///
+ /// KERB_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to
+ /// KerbQueryTicketCacheMessage or KerbRetrieveTicketMessage.
+ ///
+ ///
+ /// If this member is set to KerbQueryTicketCacheMessage, the request is for information about all of the cached tickets
+ /// for the specified user logon session. If it is set to KerbRetrieveTicketMessage, the request is for the ticket
+ /// granting ticket from the ticket cache of the specified user logon session.
+ ///
+ ///
+ public KERB_PROTOCOL_MESSAGE_TYPE MessageType;
+
+ ///
+ /// LUID structure containing the logon session identifier. This can be zero for the current user's logon session. If not zero,
+ /// the caller must have the SeTcbPrivilege privilege set. If this fails, the Kerberos authentication package sets the
+ /// ProtocolStatus parameter of LsaCallAuthenticationPackage to STATUS_ACCESS_DENIED.
+ ///
+ public LUID LogonId;
+ }
+
+ ///
+ /// The KERB_QUERY_TKT_CACHE_RESPONSE structure contains the results of querying the ticket cache.
+ /// It is used by LsaCallAuthenticationPackage.
+ ///
+ ///
+ /// This buffer is allocated by the Kerberos authentication package and should be deleted by the application that called
+ /// LsaCallAuthenticationPackage, using LsaFreeReturnBuffer.
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_query_tkt_cache_response typedef struct
+ // _KERB_QUERY_TKT_CACHE_RESPONSE { KERB_PROTOCOL_MESSAGE_TYPE MessageType; ULONG CountOfTickets; KERB_TICKET_CACHE_INFO
+ // Tickets[ANYSIZE_ARRAY]; } KERB_QUERY_TKT_CACHE_RESPONSE, *PKERB_QUERY_TKT_CACHE_RESPONSE;
+ [PInvokeData("ntsecapi.h", MSDNShortId = "2101c1de-f304-4d44-899f-f9f03cd50934")]
+ [StructLayout(LayoutKind.Sequential)]
+ [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(CountOfTickets))]
+ public struct KERB_QUERY_TKT_CACHE_RESPONSE
+ {
+ /// KERB_PROTOCOL_MESSAGE_TYPE value identifying the type of request being made. This member must be set to KerbQueryTicketCacheMessage.
+ public KERB_PROTOCOL_MESSAGE_TYPE MessageType;
+
+ ///
+ /// Number of tickets in Tickets array. This can be zero if no tickets are available for the specified logon session.
+ ///
+ public uint CountOfTickets;
+
+ /// Array of length CountOfTickets of KERB_TICKET_CACHE_INFO structures.
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
+ public KERB_TICKET_CACHE_INFO[] Tickets;
+ }
+
///
/// The KERB_RETRIEVE_TKT_REQUEST structure contains information used to retrieve a ticket.
///
@@ -2011,6 +2193,139 @@ namespace Vanara.PInvoke
public KERB_EXTERNAL_TICKET Ticket;
}
+ ///
+ ///
+ /// The KERB_TICKET_CACHE_INFO structure contains information about a cached Kerberos ticket. The Kerberos ticket is defined
+ /// in Internet RFC 4120. For more information, see http://www.ietf.org.
+ ///
+ ///
+ /// It can be used both for retrieving tickets and querying the ticket cache. The KERB_QUERY_TKT_CACHE_RESPONSE structure uses this structure.
+ ///
+ ///
+ // https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-kerb_ticket_cache_info typedef struct
+ // _KERB_TICKET_CACHE_INFO { UNICODE_STRING ServerName; UNICODE_STRING RealmName; LARGE_INTEGER StartTime; LARGE_INTEGER EndTime;
+ // LARGE_INTEGER RenewTime; LONG EncryptionType; ULONG TicketFlags; } KERB_TICKET_CACHE_INFO, *PKERB_TICKET_CACHE_INFO;
+ [PInvokeData("ntsecapi.h", MSDNShortId = "e9ac70f0-65dc-4c5a-b41f-7c4659680333")]
+ [StructLayout(LayoutKind.Sequential)]
+ public struct KERB_TICKET_CACHE_INFO
+ {
+ ///
+ /// A UNICODE_STRING that contains the name of the server the ticket applies to. This name is combined with the RealmName
+ /// value to create the full name ServerName@ RealmName.
+ ///
+ public LSA_UNICODE_STRING ServerName;
+
+ /// A UNICODE_STRING that contains the name of the realm the ticket applies to.
+ public LSA_UNICODE_STRING RealmName;
+
+ ///
+ /// A FILETIME structure that contains the time at which the ticket becomes valid. If the starttime member of the ticket
+ /// is not set, this value defaults to the time when the ticket was initially authenticated, authtime. The
+ /// starttime member of a ticket is optional.
+ ///
+ public FILETIME StartTime;
+
+ /// A FILETIME structure that contains the time when the ticket expires.
+ public FILETIME EndTime;
+
+ ///
+ /// If KERB_TICKET_FLAGS_renewable is set in TicketFlags, this member is a FILETIME structure that contains the time
+ /// beyond which the ticket cannot be renewed.
+ ///
+ public FILETIME RenewTime;
+
+ /// The type of encryption used in the ticket.
+ public KERB_ETYPE EncryptionType;
+
+ ///
+ /// The ticket flags, as defined in Internet RFC 4120. These flags can be one or more of the following values.
+ ///
+ ///
+ /// Value
+ /// Meaning
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_forwardable 0x40000000
+ ///
+ /// The ticket-granting server can issue a new ticket-granting ticket with a different network address based on the presented ticket.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_forwarded 0x20000000
+ ///
+ /// The ticket has either been forwarded or was issued based on authentication that involved a forwarded ticket-granting ticket.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_hw_authent 0x00100000
+ ///
+ /// The protocol employed for initial authentication required the use of hardware expected to be possessed solely by the named
+ /// client. The hardware authentication method is selected by the KDC and the strength of the method is not indicated.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_initial 0x00400000
+ /// The ticket was issued by using the Authentication Service protocol instead of being based on a ticket-granting ticket.
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_invalid 0x01000000
+ /// The ticket is not valid.
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_may_postdate 0x04000000
+ /// Indicates to the ticket-granting server that a postdated ticket can be issued based on this ticket-granting ticket.
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_ok_as_delegate 0x00040000
+ ///
+ /// The target of the ticket is trusted by the directory service for delegation. Thus, clients may delegate their credentials to
+ /// the server, which lets the server act as the client when talking to other services.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_postdated 0x02000000
+ ///
+ /// The ticket has been postdated. The end-service can check the ticket's authtime member to see when the original
+ /// authentication occurred.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_pre_authent 0x00200000
+ ///
+ /// During initial authentication, the client was authenticated by the Key Distribution Center (KDC) before a ticket was issued.
+ /// The strength of the preauthentication method is not indicated, but is acceptable to the KDC.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_proxiable 0x10000000
+ ///
+ /// Indicates to the ticket-granting server that only nonticket-granting tickets can be issued based on this ticket but with a
+ /// different network addresses.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_proxy 0x08000000
+ /// The ticket is a proxy.
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_renewable 0x00800000
+ ///
+ /// The ticket is renewable. If this flag is set, the time limit for renewing the ticket is set in RenewTime. A renewable ticket
+ /// can be used to obtain a replacement ticket that expires at a later date.
+ ///
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_reserved 0x80000000
+ /// Reserved for future use. Do not set this flag.
+ ///
+ /// -
+ /// KERB_TICKET_FLAGS_reserved1 0x00000001
+ /// Reserved.
+ ///
+ ///
+ ///
+ public KERB_TICKET_FLAGS TicketFlags;
+ }
/// The LSA_LAST_INTER_LOGON_INFO structure contains information about a logon session.
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/ns-ntsecapi-_lsa_last_inter_logon_info typedef struct
// _LSA_LAST_INTER_LOGON_INFO { LARGE_INTEGER LastSuccessfulLogon; LARGE_INTEGER LastFailedLogon; ULONG