ReactOS 0.4.15-dev-8096-ga0eec98
srm.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for srm.c:

Go to the source code of this file.

Classes

struct  _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION
 

Macros

#define NDEBUG
 
#define POLICY_AUDIT_EVENT_TYPE_COUNT   9
 

Typedefs

typedef struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION SEP_LOGON_SESSION_TERMINATED_NOTIFICATION
 
typedef struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATIONPSEP_LOGON_SESSION_TERMINATED_NOTIFICATION
 

Functions

VOID NTAPI SepRmCommandServerThread (_In_ PVOID StartContext)
 Manages the SRM server API commands, that is, receiving such API command messages from the user mode side of the security standpoint, the LSASS.
 
static NTSTATUS SepCleanupLUIDDeviceMapDirectory (_In_ PLUID LogonLuid)
 Cleans the DOS device map directory of a logon session.
 
static NTSTATUS SepRmCreateLogonSession (_In_ PLUID LogonLuid)
 Creates a logon session. The security reference monitoring (SRM) module of Executive uses this as an internal kernel data for respective logon sessions management within the kernel, as in form of a SEP_LOGON_SESSION_REFERENCES data structure.
 
NTSTATUS NTAPI SepRegQueryHelper (_In_ PCWSTR KeyName, _In_ PCWSTR ValueName, _In_ ULONG ValueType, _In_ ULONG DataLength, _Out_ PVOID ValueData)
 A private registry helper that returns the desired value data based on the specifics requested by the caller.
 
BOOLEAN NTAPI SeRmInitPhase0 (VOID)
 Manages the phase 0 initialization of the security reference monitoring module of the kernel.
 
BOOLEAN NTAPI SeRmInitPhase1 (VOID)
 Manages the phase 1 initialization of the security reference monitoring module of the kernel.
 
static VOID SepAdtInitializeBounds (VOID)
 Initializes the local security authority audit bounds.
 
static NTSTATUS SepRmSetAuditEvent (_Inout_ PSEP_RM_API_MESSAGE Message)
 Sets an audit event for future security auditing monitoring.
 
NTSTATUS NTAPI SepRmInsertLogonSessionIntoToken (_Inout_ PTOKEN Token)
 Inserts a logon session into an access token specified by the caller.
 
NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken (_Inout_ PTOKEN Token)
 Removes a logon session from an access token.
 
static NTSTATUS SepRmDeleteLogonSession (_In_ PLUID LogonLuid)
 Deletes a logon session from the logon sessions database.
 
NTSTATUS SepRmReferenceLogonSession (_In_ PLUID LogonLuid)
 References a logon session.
 
NTSTATUS SepRmDereferenceLogonSession (_In_ PLUID LogonLuid)
 De-references a logon session. If the session has a reference count of 0 by the time the function has de-referenced the logon, that means the session is no longer used and can be safely deleted from the logon sessions database.
 
BOOLEAN NTAPI SepRmCommandServerThreadInit (VOID)
 Main SRM server thread initialization function. It deals with security manager and LSASS port connection, thus thereby allowing communication between the kernel side (the SRM) and user mode side (the LSASS) of the security world of the operating system.
 
NTSTATUS NTAPI SeGetLogonIdDeviceMap (_In_ PLUID LogonId, _Out_ PDEVICE_MAP *DeviceMap)
 Retrieves the DOS device map from a logon session.
 
NTSTATUS NTAPI SeMarkLogonSessionForTerminationNotification (_In_ PLUID LogonId)
 Marks a logon session for future termination, given its logon ID. This triggers a callout (the registered callback) when the logon is no longer used by anyone, that is, no token is still referencing the speciffied logon session.
 
NTSTATUS NTAPI SeRegisterLogonSessionTerminatedRoutine (_In_ PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
 Registers a callback that will be called once a logon session terminates.
 
NTSTATUS NTAPI SeUnregisterLogonSessionTerminatedRoutine (_In_ PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine)
 Un-registers a callback routine, previously registered by SeRegisterLogonSessionTerminatedRoutine function.
 

Variables

LUID SeSystemAuthenticationId
 
LUID SeAnonymousAuthenticationId
 
HANDLE SeRmCommandPort
 
HANDLE SeLsaInitEvent
 
PVOID SepCommandPortViewBase
 
PVOID SepCommandPortViewRemoteBase
 
ULONG_PTR SepCommandPortViewBaseOffset
 
static HANDLE SepRmCommandMessagePort
 
BOOLEAN SepAdtAuditingEnabled
 
ULONG SepAdtMinListLength = 0x2000
 
ULONG SepAdtMaxListLength = 0x3000
 
UCHAR SeAuditingState [POLICY_AUDIT_EVENT_TYPE_COUNT]
 
KGUARDED_MUTEX SepRmDbLock
 
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions = NULL
 
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION SepLogonNotifications = NULL
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file srm.c.

◆ POLICY_AUDIT_EVENT_TYPE_COUNT

#define POLICY_AUDIT_EVENT_TYPE_COUNT   9

Definition at line 58 of file srm.c.

Typedef Documentation

◆ PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION

◆ SEP_LOGON_SESSION_TERMINATED_NOTIFICATION

Function Documentation

◆ SeGetLogonIdDeviceMap()

NTSTATUS NTAPI SeGetLogonIdDeviceMap ( _In_ PLUID  LogonId,
_Out_ PDEVICE_MAP DeviceMap 
)

Retrieves the DOS device map from a logon session.

Parameters
[in]LogonIdA valid logon session ID.
[out]DeviceMapThe returned device map buffer from the logon session.
Returns
Returns STATUS_SUCCESS if the device map could be gathered from the logon session. STATUS_INVALID_PARAMETER is returned if one of the parameters aren't initialized (that is, the caller has submitted a NULL pointer variable). STATUS_NO_SUCH_LOGON_SESSION is returned if no such session could be found. A failure NTSTATUS code is returned otherwise.

Definition at line 1347 of file srm.c.

1350{
1352 WCHAR Buffer[63];
1353 PDEVICE_MAP LocalMap;
1354 HANDLE DirectoryHandle, LinkHandle;
1356 PSEP_LOGON_SESSION_REFERENCES CurrentSession;
1357 UNICODE_STRING DirectoryName, LinkName, TargetName;
1358
1359 PAGED_CODE();
1360
1361 if (LogonId == NULL ||
1362 DeviceMap == NULL)
1363 {
1365 }
1366
1367 /* Acquire the database lock */
1369
1370 /* Loop all existing sessions */
1371 for (CurrentSession = SepLogonSessions;
1372 CurrentSession != NULL;
1373 CurrentSession = CurrentSession->Next)
1374 {
1375 /* Check if the LUID matches the provided one */
1376 if (RtlEqualLuid(&CurrentSession->LogonId, LogonId))
1377 {
1378 break;
1379 }
1380 }
1381
1382 /* No session found, fail */
1383 if (CurrentSession == NULL)
1384 {
1385 /* Release the database lock */
1387
1389 }
1390
1391 /* The found session has a device map, return it! */
1392 if (CurrentSession->pDeviceMap != NULL)
1393 {
1394 *DeviceMap = CurrentSession->pDeviceMap;
1395
1396 /* Release the database lock */
1398
1399 return STATUS_SUCCESS;
1400 }
1401
1402 /* At that point, we'll setup a new device map for the session */
1403 LocalMap = NULL;
1404
1405 /* Reference the session so that it doesn't go away */
1406 CurrentSession->ReferenceCount += 1;
1407
1408 /* Release the database lock */
1410
1411 /* Create our object directory given the LUID */
1413 sizeof(Buffer) / sizeof(WCHAR),
1414 L"\\Sessions\\0\\DosDevices\\%08x-%08x",
1415 LogonId->HighPart,
1416 LogonId->LowPart);
1417 RtlInitUnicodeString(&DirectoryName, Buffer);
1418
1420 &DirectoryName,
1422 NULL,
1423 NULL);
1427 if (NT_SUCCESS(Status))
1428 {
1429 /* Create the associated device map */
1431 if (NT_SUCCESS(Status))
1432 {
1433 /* Make Global point to \Global?? in the directory */
1434 RtlInitUnicodeString(&LinkName, L"Global");
1435 RtlInitUnicodeString(&TargetName, L"\\Global??");
1436
1438 &LinkName,
1441 NULL);
1442 Status = ZwCreateSymbolicLinkObject(&LinkHandle,
1445 &TargetName);
1446 if (!NT_SUCCESS(Status))
1447 {
1448 ObfDereferenceDeviceMap(LocalMap);
1449 }
1450 else
1451 {
1452 ZwClose(LinkHandle);
1453 }
1454 }
1455
1457 }
1458
1459 /* Acquire the database lock */
1461
1462 /* If we succeed... */
1463 if (NT_SUCCESS(Status))
1464 {
1465 /* The session now has a device map? We raced with someone else */
1466 if (CurrentSession->pDeviceMap != NULL)
1467 {
1468 /* Give up on our new device map */
1469 ObfDereferenceDeviceMap(LocalMap);
1470 }
1471 /* Otherwise use our newly allocated device map */
1472 else
1473 {
1474 CurrentSession->pDeviceMap = LocalMap;
1475 }
1476
1477 /* Return the device map */
1478 *DeviceMap = CurrentSession->pDeviceMap;
1479 }
1480 /* Zero output */
1481 else
1482 {
1483 *DeviceMap = NULL;
1484 }
1485
1486 /* Release the database lock */
1488
1489 /* We're done with the session */
1490 SepRmDereferenceLogonSession(&CurrentSession->LogonId);
1491
1492 return Status;
1493}
#define PAGED_CODE()
static HANDLE DirectoryHandle
Definition: ObType.c:48
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_PERMANENT
Definition: winternl.h:226
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI ZwCreateSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ PUNICODE_STRING Name)
NTSYSAPI NTSTATUS NTAPI ZwCreateDirectoryObject(_Out_ PHANDLE DirectoryHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID LogonId
NTSTATUS SepRmDereferenceLogonSession(_In_ PLUID LogonLuid)
De-references a logon session. If the session has a reference count of 0 by the time the function has...
Definition: srm.c:1008
KGUARDED_MUTEX SepRmDbLock
Definition: srm.c:61
PSEP_LOGON_SESSION_REFERENCES SepLogonSessions
Definition: srm.c:62
#define STATUS_NO_SUCH_LOGON_SESSION
Definition: ntstatus.h:331
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObSetDirectoryDeviceMap(OUT PDEVICE_MAP *DeviceMap, IN HANDLE DirectoryHandle)
Definition: devicemap.c:149
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
static PCWSTR TargetName
Definition: ping.c:67
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _SEP_LOGON_SESSION_REFERENCES * Next
Definition: setypes.h:169
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ObpReferenceDeviceMap(), and ObpSetCurrentProcessDeviceMap().

◆ SeMarkLogonSessionForTerminationNotification()

NTSTATUS NTAPI SeMarkLogonSessionForTerminationNotification ( _In_ PLUID  LogonId)

Marks a logon session for future termination, given its logon ID. This triggers a callout (the registered callback) when the logon is no longer used by anyone, that is, no token is still referencing the speciffied logon session.

Parameters
[in]LogonIdThe ID of the logon session.
Returns
STATUS_SUCCESS if the logon session is marked for termination notification successfully, STATUS_NOT_FOUND if the logon session couldn't be found otherwise.

Definition at line 1510 of file srm.c.

1512{
1513 PSEP_LOGON_SESSION_REFERENCES SessionToMark;
1514 PAGED_CODE();
1515
1516 DPRINT("SeMarkLogonSessionForTerminationNotification(%08lx:%08lx)\n",
1517 LogonId->HighPart, LogonId->LowPart);
1518
1519 /* Acquire the database lock */
1521
1522 /* Loop over the existing logon sessions */
1523 for (SessionToMark = SepLogonSessions;
1524 SessionToMark != NULL;
1525 SessionToMark = SessionToMark->Next)
1526 {
1527 /* Does the logon with the given ID exist? */
1528 if (RtlEqualLuid(&SessionToMark->LogonId, LogonId))
1529 {
1530 /* We found it */
1531 break;
1532 }
1533 }
1534
1535 /*
1536 * We've exhausted all the remaining logon sessions and
1537 * couldn't find one with the provided ID.
1538 */
1539 if (SessionToMark == NULL)
1540 {
1541 DPRINT1("SeMarkLogonSessionForTerminationNotification(): Logon session couldn't be found!\n");
1543 return STATUS_NOT_FOUND;
1544 }
1545
1546 /* Mark the logon session for termination */
1548 DPRINT("SeMarkLogonSessionForTerminationNotification(): Logon session marked for termination with success!\n");
1549
1550 /* Release the database lock */
1552 return STATUS_SUCCESS;
1553}
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define DPRINT
Definition: sndvol32.h:73
#define SEP_LOGON_SESSION_TERMINATION_NOTIFY
Definition: setypes.h:708

Referenced by LogonMarkTermination().

◆ SepAdtInitializeBounds()

static VOID SepAdtInitializeBounds ( VOID  )
static

Initializes the local security authority audit bounds.

Returns
Nothing.

Definition at line 274 of file srm.c.

275{
276 struct
277 {
278 ULONG MaxLength;
279 ULONG MinLength;
280 } ListBounds;
282 PAGED_CODE();
283
284 Status = SepRegQueryHelper(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Lsa",
285 L"Bounds",
287 sizeof(ListBounds),
288 &ListBounds);
289 if (!NT_SUCCESS(Status))
290 {
291 /* No registry values, so keep hardcoded defaults */
292 return;
293 }
294
295 /* Check if the bounds are valid */
296 if ((ListBounds.MaxLength < ListBounds.MinLength) ||
297 (ListBounds.MinLength < 16) ||
298 (ListBounds.MaxLength - ListBounds.MinLength < 16))
299 {
300 DPRINT1("ListBounds are invalid: %u, %u\n",
301 ListBounds.MinLength, ListBounds.MaxLength);
302 return;
303 }
304
305 /* Set the new bounds globally */
306 SepAdtMinListLength = ListBounds.MinLength;
307 SepAdtMaxListLength = ListBounds.MaxLength;
308}
#define REG_BINARY
Definition: nt_native.h:1496
NTSTATUS NTAPI SepRegQueryHelper(_In_ PCWSTR KeyName, _In_ PCWSTR ValueName, _In_ ULONG ValueType, _In_ ULONG DataLength, _Out_ PVOID ValueData)
A private registry helper that returns the desired value data based on the specifics requested by the...
Definition: srm.c:93
ULONG SepAdtMinListLength
Definition: srm.c:55
ULONG SepAdtMaxListLength
Definition: srm.c:56
uint32_t ULONG
Definition: typedefs.h:59

Referenced by SepRmSetAuditEvent().

◆ SepCleanupLUIDDeviceMapDirectory()

static NTSTATUS SepCleanupLUIDDeviceMapDirectory ( _In_ PLUID  LogonLuid)
static

Cleans the DOS device map directory of a logon session.

Parameters
[in]LogonLuidA logon session ID where its DOS device map directory is to be cleaned.
Returns
Returns STATUS_SUCCESS if the device map directory has been successfully cleaned from the logon session. STATUS_INVALID_PARAMETER is returned if the caller hasn't submitted any logon ID. STATUS_NO_MEMORY is returned if buffer allocation for links has failed. A failure NTSTATUS code is returned otherwise.

Definition at line 751 of file srm.c.

753{
754 BOOLEAN UseCurrentProc;
756 WCHAR Buffer[63];
757 UNICODE_STRING DirectoryName;
760 HANDLE DirectoryHandle, LinkHandle;
761 PHANDLE LinksBuffer;
762 POBJECT_DIRECTORY_INFORMATION DirectoryInfo;
763 ULONG LinksCount, LinksSize, DirInfoLength, ReturnLength, Context, CurrentLinks, i;
765
766 PAGED_CODE();
767
768 /* We need a logon LUID */
769 if (LogonLuid == NULL)
770 {
772 }
773
774 /* Use current process */
775 UseCurrentProc = ObReferenceObjectSafe(PsGetCurrentProcess());
776 if (UseCurrentProc)
777 {
779 }
780 /* Unless it's gone, then use system process */
781 else
782 {
784 }
785
786 /* Initialize our directory name */
788 sizeof(Buffer) / sizeof(WCHAR),
789 L"\\Sessions\\0\\DosDevices\\%08x-%08x",
790 LogonLuid->HighPart,
791 LogonLuid->LowPart);
792 RtlInitUnicodeString(&DirectoryName, Buffer);
793
794 /* And open it */
796 &DirectoryName,
798 NULL,
799 NULL);
803 if (!NT_SUCCESS(Status))
804 {
805 if (!UseCurrentProc)
806 {
808 }
809
810 return Status;
811 }
812
813 /* Some initialization needed for browsing all our links... */
814 Context = 0;
815 DirectoryInfo = NULL;
816 DirInfoLength = 0;
817 /* In our buffer, we'll store at max 100 HANDLE */
818 LinksCount = 100;
819 CurrentLinks = 0;
820 /* Which gives a certain size */
821 LinksSize = LinksCount * sizeof(HANDLE);
822
823 /*
824 * This label is hit if we need to store more than a hundred
825 * of links. In that case, we jump here after having cleaned
826 * and deleted previous buffer.
827 * All handles have been already closed
828 */
829AllocateLinksAgain:
830 LinksBuffer = ExAllocatePoolWithTag(PagedPool,
831 LinksSize,
833 if (LinksBuffer == NULL)
834 {
835 /*
836 * Failure path: no need to clear handles:
837 * already closed and the buffer is already gone
838 */
840
841 /*
842 * On the first round, DirectoryInfo is NULL,
843 * if we grow LinksBuffer, it has been allocated
844 */
845 if (DirectoryInfo != NULL)
846 {
847 ExFreePoolWithTag(DirectoryInfo, TAG_SE_DIR_BUFFER);
848 }
849
850 if (!UseCurrentProc)
851 {
853 }
854
855 return STATUS_NO_MEMORY;
856 }
857
858 /*
859 * We always restart scan, but on the first loop
860 * if we couldn't fit everything in our buffer,
861 * then, we continue scan.
862 * But we restart if link buffer was too small
863 */
864 for (RestartScan = TRUE; ; RestartScan = FALSE)
865 {
866 /*
867 * Loop until our buffer is big enough to store
868 * one entry
869 */
870 while (TRUE)
871 {
872 Status = ZwQueryDirectoryObject(DirectoryHandle,
873 DirectoryInfo,
874 DirInfoLength,
875 TRUE,
877 &Context,
878 &ReturnLength);
879 /* Only handle buffer growth in that loop */
881 {
882 break;
883 }
884
885 /* Get output length as new length */
886 DirInfoLength = ReturnLength;
887 /* Delete old buffer if any */
888 if (DirectoryInfo != NULL)
889 {
890 ExFreePoolWithTag(DirectoryInfo, 'bDeS');
891 }
892
893 /* And reallocate a bigger one */
894 DirectoryInfo = ExAllocatePoolWithTag(PagedPool,
895 DirInfoLength,
897 /* Fail if we cannot allocate */
898 if (DirectoryInfo == NULL)
899 {
901 break;
902 }
903 }
904
905 /* If querying the entry failed, quit */
906 if (!NT_SUCCESS(Status))
907 {
908 break;
909 }
910
911 /* We only look for symbolic links, the rest, we ignore */
912 if (wcscmp(DirectoryInfo->TypeName.Buffer, L"SymbolicLink"))
913 {
914 continue;
915 }
916
917 /* If our link buffer is out of space, reallocate */
918 if (CurrentLinks >= LinksCount)
919 {
920 /* First, close the links */
921 for (i = 0; i < CurrentLinks; ++i)
922 {
923 ZwClose(LinksBuffer[i]);
924 }
925
926 /* Allow 20 more HANDLEs */
927 LinksCount += 20;
928 CurrentLinks = 0;
930 LinksSize = LinksCount * sizeof(HANDLE);
931
932 /* And reloop again */
933 goto AllocateLinksAgain;
934 }
935
936 /* Open the found link */
938 &DirectoryInfo->Name,
941 NULL);
942 if (NT_SUCCESS(ZwOpenSymbolicLinkObject(&LinkHandle,
945 {
946 /* If we cannot make it temporary, just close the link handle */
947 if (!NT_SUCCESS(ZwMakeTemporaryObject(LinkHandle)))
948 {
949 ZwClose(LinkHandle);
950 }
951 /* Otherwise, store it to defer deletion */
952 else
953 {
954 LinksBuffer[CurrentLinks] = LinkHandle;
955 ++CurrentLinks;
956 }
957 }
958 }
959
960 /* No more entries means we handled all links, that's not a failure */
962 {
964 }
965
966 /* Close all the links we stored, this will like cause their deletion */
967 for (i = 0; i < CurrentLinks; ++i)
968 {
969 ZwClose(LinksBuffer[i]);
970 }
971 /* And free our links buffer */
973
974 /* Free our directory info buffer - it might be NULL if we failed realloc */
975 if (DirectoryInfo != NULL)
976 {
977 ExFreePoolWithTag(DirectoryInfo, TAG_SE_DIR_BUFFER);
978 }
979
980 /* Close our session directory */
982
983 /* And detach from system */
984 if (!UseCurrentProc)
985 {
987 }
988
989 return Status;
990}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2299
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwOpenDirectoryObject(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwMakeTemporaryObject(_In_ HANDLE Handle)
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:22
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
KPROCESS Pcb
Definition: pstypes.h:1262
UNICODE_STRING TypeName
Definition: obtypes.h:279
#define TAG_SE_DIR_BUFFER
Definition: tag.h:160
#define TAG_SE_HANDLES_TAB
Definition: tag.h:159
PVOID HANDLE
Definition: typedefs.h:73
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
KAPC_STATE
Definition: ketypes.h:1409
#define ObDereferenceObject
Definition: obfuncs.h:203
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by SepRmDeleteLogonSession(), and SepRmDereferenceLogonSession().

◆ SepRegQueryHelper()

NTSTATUS NTAPI SepRegQueryHelper ( _In_ PCWSTR  KeyName,
_In_ PCWSTR  ValueName,
_In_ ULONG  ValueType,
_In_ ULONG  DataLength,
_Out_ PVOID  ValueData 
)

A private registry helper that returns the desired value data based on the specifics requested by the caller.

Parameters
[in]KeyNameName of the key.
[in]ValueNameName of the registry value.
[in]ValueTypeThe type of the registry value.
[in]DataLengthThe data length, in bytes, representing the size of the registry value.
[out]ValueDataThe requested value data provided by the function.
Returns
Returns STATUS_SUCCESS if the operations have completed successfully, otherwise a failure NTSTATUS code is returned.

Definition at line 93 of file srm.c.

99{
100 UNICODE_STRING ValueNameString;
101 UNICODE_STRING KeyNameString;
105 struct
106 {
108 UCHAR Buffer[64];
109 } KeyValueInformation;
110 NTSTATUS Status, CloseStatus;
111 PAGED_CODE();
112
113 RtlInitUnicodeString(&KeyNameString, KeyName);
115 &KeyNameString,
117 NULL,
118 NULL);
119
121 if (!NT_SUCCESS(Status))
122 {
123 return Status;
124 }
125
126 RtlInitUnicodeString(&ValueNameString, ValueName);
127 Status = ZwQueryValueKey(KeyHandle,
128 &ValueNameString,
130 &KeyValueInformation.Partial,
131 sizeof(KeyValueInformation),
132 &ResultLength);
133 if (!NT_SUCCESS(Status))
134 {
135 goto Cleanup;
136 }
137
138 if ((KeyValueInformation.Partial.Type != ValueType) ||
139 (KeyValueInformation.Partial.DataLength != DataLength))
140 {
142 goto Cleanup;
143 }
144
145 if (ValueType == REG_BINARY)
146 {
147 RtlCopyMemory(ValueData, KeyValueInformation.Partial.Data, DataLength);
148 }
149 else if (ValueType == REG_DWORD)
150 {
151 *(PULONG)ValueData = *(PULONG)KeyValueInformation.Partial.Data;
152 }
153 else
154 {
156 }
157
158Cleanup:
159 CloseStatus = ZwClose(KeyHandle);
160 ASSERT(NT_SUCCESS( CloseStatus ));
161
162 return Status;
163}
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
static const WCHAR Cleanup[]
Definition: register.c:80
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define ASSERT(a)
Definition: mode.c:44
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
#define REG_DWORD
Definition: sdbapi.c:596
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3776
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by SepAdtInitializeBounds(), and SepImpersonateAnonymousToken().

◆ SepRmCommandServerThread()

VOID NTAPI SepRmCommandServerThread ( _In_ PVOID  StartContext)

Manages the SRM server API commands, that is, receiving such API command messages from the user mode side of the security standpoint, the LSASS.

Returns
Nothing.

Definition at line 1226 of file srm.c.

1228{
1231 HANDLE DummyPortHandle;
1233
1234 /* Initialize the server thread */
1236 {
1237 DPRINT1("Security: Terminating Rm Command Server Thread\n");
1238 return;
1239 }
1240
1241 /* No reply yet */
1243
1244 /* Start looping */
1245 while (TRUE)
1246 {
1247 /* Wait for a message */
1249 NULL,
1251 &Message.Header);
1252 if (!NT_SUCCESS(Status))
1253 {
1254 DPRINT1("Failed to get message: 0x%lx", Status);
1256 continue;
1257 }
1258
1259 /* Check if this is a connection request */
1260 if (Message.Header.u2.s2.Type == LPC_CONNECTION_REQUEST)
1261 {
1262 /* Reject connection request */
1263 ZwAcceptConnectPort(&DummyPortHandle,
1264 NULL,
1265 &Message.Header,
1266 FALSE,
1267 NULL,
1268 NULL);
1269
1270 /* Start over */
1272 continue;
1273 }
1274
1275 /* Check if the port died */
1276 if ((Message.Header.u2.s2.Type == LPC_PORT_CLOSED) ||
1277 (Message.Header.u2.s2.Type == LPC_CLIENT_DIED))
1278 {
1279 /* LSASS is dead, so let's quit as well */
1280 break;
1281 }
1282
1283 /* Check if this is an actual request */
1284 if (Message.Header.u2.s2.Type != LPC_REQUEST)
1285 {
1286 DPRINT1("SepRmCommandServerThread: unexpected message type: 0x%lx\n",
1287 Message.Header.u2.s2.Type);
1288
1289 /* Restart without replying */
1291 continue;
1292 }
1293
1294 ReplyMessage = &Message.Header;
1295
1296 switch (Message.ApiNumber)
1297 {
1298 case RmAuditSetCommand:
1300 break;
1301
1303 Status = SepRmCreateLogonSession(&Message.u.LogonLuid);
1304 break;
1305
1307 Status = SepRmDeleteLogonSession(&Message.u.LogonLuid);
1308 break;
1309
1310 default:
1311 DPRINT1("SepRmDispatchRequest: invalid API number: 0x%lx\n",
1312 Message.ApiNumber);
1314 }
1315
1316 Message.u.ResultStatus = Status;
1317 }
1318
1319 /* Close the port handles */
1322}
HANDLE SeRmCommandPort
Definition: srm.c:18
static const WCHAR Message[]
Definition: register.c:74
NTSYSAPI NTSTATUS NTAPI ZwReplyWaitReceivePort(_In_ HANDLE PortHandle, _Out_opt_ PVOID *PortContext, _In_opt_ PPORT_MESSAGE ReplyMessage, _Out_ PPORT_MESSAGE ReceiveMessage)
NTSYSAPI NTSTATUS NTAPI ZwAcceptConnectPort(_Out_ PHANDLE PortHandle, _In_opt_ PVOID PortContext, _In_ PPORT_MESSAGE ConnectionRequest, _In_ BOOLEAN AcceptConnection, _In_opt_ PPORT_VIEW ServerView, _In_opt_ PREMOTE_PORT_VIEW ClientView)
#define LPC_CLIENT_DIED
Definition: port.c:98
#define LPC_REQUEST
Definition: port.c:93
#define LPC_CONNECTION_REQUEST
Definition: port.c:102
#define LPC_PORT_CLOSED
Definition: port.c:97
#define KernelMode
Definition: asm.h:34
static NTSTATUS SepRmDeleteLogonSession(_In_ PLUID LogonLuid)
Deletes a logon session from the logon sessions database.
Definition: srm.c:590
static HANDLE SepRmCommandMessagePort
Definition: srm.c:52
static NTSTATUS SepRmCreateLogonSession(_In_ PLUID LogonLuid)
Creates a logon session. The security reference monitoring (SRM) module of Executive uses this as an ...
Definition: srm.c:512
BOOLEAN NTAPI SepRmCommandServerThreadInit(VOID)
Main SRM server thread initialization function. It deals with security manager and LSASS port connect...
Definition: srm.c:1075
static NTSTATUS SepRmSetAuditEvent(_Inout_ PSEP_RM_API_MESSAGE Message)
Sets an audit event for future security auditing monitoring.
Definition: srm.c:324
NTSTATUS NTAPI ObCloseHandle(IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode)
Definition: obhandle.c:3379
@ RmDeleteLogonSession
Definition: srmp.h:8
@ RmAuditSetCommand
Definition: srmp.h:6
@ RmCreateLogonSession
Definition: srmp.h:7
BOOL WINAPI ReplyMessage(_In_ LRESULT)

Referenced by SeRmInitPhase1().

◆ SepRmCommandServerThreadInit()

BOOLEAN NTAPI SepRmCommandServerThreadInit ( VOID  )

Main SRM server thread initialization function. It deals with security manager and LSASS port connection, thus thereby allowing communication between the kernel side (the SRM) and user mode side (the LSASS) of the security world of the operating system.

Returns
Returns TRUE if command server connection between SRM and LSASS has succeeded, FALSE otherwise.

Definition at line 1075 of file srm.c.

1076{
1077 SECURITY_QUALITY_OF_SERVICE SecurityQos;
1080 REMOTE_PORT_VIEW RemotePortView;
1081 PORT_VIEW PortView;
1082 LARGE_INTEGER SectionSize;
1083 HANDLE SectionHandle;
1084 HANDLE PortHandle;
1087
1088 SectionHandle = NULL;
1089 PortHandle = NULL;
1090
1091 /* Assume success */
1092 Result = TRUE;
1093
1094 /* Wait until LSASS is ready */
1095 Status = ZwWaitForSingleObject(SeLsaInitEvent, FALSE, NULL);
1096 if (!NT_SUCCESS(Status))
1097 {
1098 DPRINT1("Security Rm Init: Waiting for LSA Init Event failed 0x%lx\n", Status);
1099 goto Cleanup;
1100 }
1101
1102 /* We don't need this event anymore */
1104
1105 /* Initialize the connection message */
1106 Message.Header.u1.s1.TotalLength = sizeof(Message);
1107 Message.Header.u1.s1.DataLength = 0;
1108
1109 /* Only LSASS can connect, so handle the connection right now */
1111 if (!NT_SUCCESS(Status))
1112 {
1113 DPRINT1("Security Rm Init: Listen to Command Port failed 0x%lx\n", Status);
1114 goto Cleanup;
1115 }
1116
1117 /* Set the Port View structure length */
1118 RemotePortView.Length = sizeof(RemotePortView);
1119
1120 /* Accept the connection */
1122 NULL,
1123 &Message.Header,
1124 TRUE,
1125 NULL,
1126 &RemotePortView);
1127 if (!NT_SUCCESS(Status))
1128 {
1129 DPRINT1("Security Rm Init: Accept Connect to Command Port failed 0x%lx\n", Status);
1130 goto Cleanup;
1131 }
1132
1133 /* Complete the connection */
1135 if (!NT_SUCCESS(Status))
1136 {
1137 DPRINT1("Security Rm Init: Complete Connect to Command Port failed 0x%lx\n", Status);
1138 goto Cleanup;
1139 }
1140
1141 /* Create a section for messages */
1142 SectionSize.QuadPart = PAGE_SIZE;
1143 Status = ZwCreateSection(&SectionHandle,
1145 NULL,
1146 &SectionSize,
1148 SEC_COMMIT,
1149 NULL);
1150 if (!NT_SUCCESS(Status))
1151 {
1152 DPRINT1("Security Rm Init: Create Memory Section for LSA port failed: %X\n", Status);
1153 goto Cleanup;
1154 }
1155
1156 /* Setup the PORT_VIEW structure */
1157 PortView.Length = sizeof(PortView);
1158 PortView.SectionHandle = SectionHandle;
1159 PortView.SectionOffset = 0;
1160 PortView.ViewSize = SectionSize.LowPart;
1161 PortView.ViewBase = NULL;
1162 PortView.ViewRemoteBase = NULL;
1163
1164 /* Setup security QOS */
1165 SecurityQos.Length = sizeof(SecurityQos);
1168 SecurityQos.EffectiveOnly = TRUE;
1169
1170 /* Connect to LSASS */
1171 RtlInitUnicodeString(&PortName, L"\\SeLsaCommandPort");
1172 Status = ZwConnectPort(&PortHandle,
1173 &PortName,
1174 &SecurityQos,
1175 &PortView,
1176 NULL,
1177 0,
1178 0,
1179 0);
1180 if (!NT_SUCCESS(Status))
1181 {
1182 DPRINT1("Security Rm Init: Connect to LSA Port failed 0x%lx\n", Status);
1183 goto Cleanup;
1184 }
1185
1186 /* Remember section base and view offset */
1191
1192 DPRINT("SepRmCommandServerThreadInit: done\n");
1193
1194Cleanup:
1195 /* Check for failure */
1196 if (!NT_SUCCESS(Status))
1197 {
1198 if (PortHandle != NULL)
1199 {
1200 ObCloseHandle(PortHandle, KernelMode);
1201 }
1202
1203 Result = FALSE;
1204 }
1205
1206 /* Did we create a section? */
1207 if (SectionHandle != NULL)
1208 {
1209 ObCloseHandle(SectionHandle, KernelMode);
1210 }
1211
1212 return Result;
1213}
static UNICODE_STRING PortName
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSYSAPI NTSTATUS NTAPI ZwListenPort(_In_ HANDLE PortHandle, _In_ PPORT_MESSAGE ConnectionRequest)
NTSYSAPI NTSTATUS NTAPI ZwConnectPort(_Out_ PHANDLE PortHandle, _In_ PUNICODE_STRING PortName, _In_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _In_opt_ PPORT_VIEW ClientView, _In_opt_ PREMOTE_PORT_VIEW ServerView, _In_opt_ PULONG MaxMessageLength, _In_opt_ PVOID ConnectionInformation, _In_opt_ PULONG ConnectionInformationLength)
NTSYSAPI NTSTATUS NTAPI ZwCompleteConnectPort(_In_ HANDLE PortHandle)
@ SecurityImpersonation
Definition: lsa.idl:57
#define SEC_COMMIT
Definition: mmtypes.h:100
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1293
HANDLE SeLsaInitEvent
Definition: srm.c:46
PVOID SepCommandPortViewBase
Definition: srm.c:48
PVOID SepCommandPortViewRemoteBase
Definition: srm.c:49
ULONG_PTR SepCommandPortViewBaseOffset
Definition: srm.c:50
LPC_PVOID ViewBase
LPC_HANDLE SectionHandle
LPC_PVOID ViewRemoteBase
ULONG SectionOffset
LPC_SIZE_T ViewSize
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
uint32_t ULONG_PTR
Definition: typedefs.h:65
LONGLONG QuadPart
Definition: typedefs.h:114
ULONG LowPart
Definition: typedefs.h:106
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103

Referenced by SepRmCommandServerThread().

◆ SepRmCreateLogonSession()

static NTSTATUS SepRmCreateLogonSession ( _In_ PLUID  LogonLuid)
static

Creates a logon session. The security reference monitoring (SRM) module of Executive uses this as an internal kernel data for respective logon sessions management within the kernel, as in form of a SEP_LOGON_SESSION_REFERENCES data structure.

Parameters
[in]LogonLuidA logon ID represented as a LUID. This LUID is used to create our logon session and add it to the sessions database.
Returns
Returns STATUS_SUCCESS if the logon has been created successfully. STATUS_LOGON_SESSION_EXISTS is returned if a logon session with the pointed logon ID in the call already exists. STATUS_INSUFFICIENT_RESOURCES is returned if logon session allocation has failed because of lack of memory pool resources.

Definition at line 512 of file srm.c.

514{
515 PSEP_LOGON_SESSION_REFERENCES CurrentSession, NewSession;
517 PAGED_CODE();
518
519 DPRINT("SepRmCreateLogonSession(%08lx:%08lx)\n",
520 LogonLuid->HighPart, LogonLuid->LowPart);
521
522 /* Allocate a new session structure */
523 NewSession = ExAllocatePoolWithTag(PagedPool,
526 if (NewSession == NULL)
527 {
529 }
530
531 /* Initialize it */
532 NewSession->LogonId = *LogonLuid;
533 NewSession->ReferenceCount = 0;
534 NewSession->Flags = 0;
535 NewSession->pDeviceMap = NULL;
536 InitializeListHead(&NewSession->TokenList);
537
538 /* Acquire the database lock */
540
541 /* Loop all existing sessions */
542 for (CurrentSession = SepLogonSessions;
543 CurrentSession != NULL;
544 CurrentSession = CurrentSession->Next)
545 {
546 /* Check if the LUID matches the new one */
547 if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
548 {
550 goto Leave;
551 }
552 }
553
554 /* Insert the new session */
555 NewSession->Next = SepLogonSessions;
556 SepLogonSessions = NewSession;
557
559
560Leave:
561 /* Release the database lock */
563
564 if (!NT_SUCCESS(Status))
565 {
567 }
568
569 return Status;
570}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_LOGON_SESSION_EXISTS
Definition: ntstatus.h:474
#define TAG_LOGON_SESSION
Definition: tag.h:163

Referenced by SepRmCommandServerThread(), and SeRmInitPhase0().

◆ SepRmDeleteLogonSession()

static NTSTATUS SepRmDeleteLogonSession ( _In_ PLUID  LogonLuid)
static

Deletes a logon session from the logon sessions database.

Parameters
[in]LogonLuidA logon ID represented as a LUID. This LUID is used to point the exact logon session saved within the database.
Returns
STATUS_SUCCESS is returned if the logon session has been deleted successfully. STATUS_NO_SUCH_LOGON_SESSION is returned if the logon session with the submitted LUID doesn't exist. STATUS_BAD_LOGON_SESSION_STATE is returned if the logon session is still in use and we're not allowed to delete it, or if a system or anonymous session is submitted and we're not allowed to delete them as they're internal parts of the system. Otherwise a failure NTSTATUS code is returned.

Definition at line 590 of file srm.c.

592{
593 PSEP_LOGON_SESSION_REFERENCES SessionToDelete;
595 PAGED_CODE();
596
597 DPRINT("SepRmDeleteLogonSession(%08lx:%08lx)\n",
598 LogonLuid->HighPart, LogonLuid->LowPart);
599
600 /* Acquire the database lock */
602
603 /* Loop over the existing logon sessions */
604 for (SessionToDelete = SepLogonSessions;
605 SessionToDelete != NULL;
606 SessionToDelete = SessionToDelete->Next)
607 {
608 /*
609 * Does the actual logon session exist in the
610 * saved logon sessions database with the LUID
611 * provided?
612 */
613 if (RtlEqualLuid(&SessionToDelete->LogonId, LogonLuid))
614 {
615 /* Did the caller supply one of these internal sessions? */
616 if (RtlEqualLuid(&SessionToDelete->LogonId, &SeSystemAuthenticationId) ||
618 {
619 /* These logons are critical stuff, we can't delete them */
620 DPRINT1("SepRmDeleteLogonSession(): We're not allowed to delete anonymous/system sessions!\n");
622 goto Leave;
623 }
624 else
625 {
626 /* We found the logon as exactly as we wanted, break the loop */
627 break;
628 }
629 }
630 }
631
632 /*
633 * If we reach this then that means we've exhausted all the logon
634 * sessions and couldn't find one with the desired LUID.
635 */
636 if (SessionToDelete == NULL)
637 {
638 DPRINT1("SepRmDeleteLogonSession(): The logon session with this LUID doesn't exist!\n");
640 goto Leave;
641 }
642
643 /* Is somebody still using this logon session? */
644 if (SessionToDelete->ReferenceCount != 0)
645 {
646 /* The logon session is still in use, we cannot delete it... */
647 DPRINT1("SepRmDeleteLogonSession(): The logon session is still in use!\n");
649 goto Leave;
650 }
651
652 /* If we have a LUID device map, clean it */
653 if (SessionToDelete->pDeviceMap != NULL)
654 {
656 if (!NT_SUCCESS(Status))
657 {
658 /*
659 * We had one job on cleaning the device map directory
660 * of the logon session but we failed, quit...
661 */
662 DPRINT1("SepRmDeleteLogonSession(): Failed to clean the LUID device map directory of the logon (Status: 0x%lx)\n", Status);
663 goto Leave;
664 }
665
666 /* And dereference the device map of the logon */
667 ObfDereferenceDeviceMap(SessionToDelete->pDeviceMap);
668 }
669
670 /* If we're here then we've deleted the logon session successfully */
671 DPRINT("SepRmDeleteLogonSession(): Logon session deleted with success!\n");
673 ExFreePoolWithTag(SessionToDelete, TAG_LOGON_SESSION);
674
675Leave:
676 /* Release the database lock */
678 return Status;
679}
LUID SeSystemAuthenticationId
Definition: token.c:20
static NTSTATUS SepCleanupLUIDDeviceMapDirectory(_In_ PLUID LogonLuid)
Cleans the DOS device map directory of a logon session.
Definition: srm.c:751
LUID SeAnonymousAuthenticationId
Definition: token.c:21
#define STATUS_BAD_LOGON_SESSION_STATE
Definition: ntstatus.h:496

Referenced by SepRmCommandServerThread().

◆ SepRmDereferenceLogonSession()

NTSTATUS SepRmDereferenceLogonSession ( _In_ PLUID  LogonLuid)

De-references a logon session. If the session has a reference count of 0 by the time the function has de-referenced the logon, that means the session is no longer used and can be safely deleted from the logon sessions database.

Parameters
[in]LogonLuidA logon session ID to de-reference.
Returns
Returns STATUS_SUCCESS if the logon session has been de-referenced without issues. STATUS_NO_SUCH_LOGON_SESSION is returned if no such logon exists otherwise.

Definition at line 1008 of file srm.c.

1010{
1011 ULONG RefCount;
1012 PDEVICE_MAP DeviceMap;
1013 PSEP_LOGON_SESSION_REFERENCES CurrentSession;
1014
1015 DPRINT("SepRmDereferenceLogonSession(%08lx:%08lx)\n",
1016 LogonLuid->HighPart, LogonLuid->LowPart);
1017
1018 /* Acquire the database lock */
1020
1021 /* Loop all existing sessions */
1022 for (CurrentSession = SepLogonSessions;
1023 CurrentSession != NULL;
1024 CurrentSession = CurrentSession->Next)
1025 {
1026 /* Check if the LUID matches the new one */
1027 if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
1028 {
1029 /* Dereference the session */
1030 RefCount = --CurrentSession->ReferenceCount;
1031 DPRINT("ReferenceCount: %lu\n", CurrentSession->ReferenceCount);
1032
1033 /* Release the database lock */
1035
1036 /* We're done with the session */
1037 if (RefCount == 0)
1038 {
1039 /* Get rid of the LUID device map */
1040 DeviceMap = CurrentSession->pDeviceMap;
1041 if (DeviceMap != NULL)
1042 {
1043 CurrentSession->pDeviceMap = NULL;
1045 ObfDereferenceDeviceMap(DeviceMap);
1046 }
1047
1048 /* FIXME: Alert LSA and filesystems that a logon is about to be deleted */
1049 }
1050
1051 return STATUS_SUCCESS;
1052 }
1053 }
1054
1055 /* Release the database lock */
1057
1059}

Referenced by SeGetLogonIdDeviceMap().

◆ SepRmInsertLogonSessionIntoToken()

NTSTATUS NTAPI SepRmInsertLogonSessionIntoToken ( _Inout_ PTOKEN  Token)

Inserts a logon session into an access token specified by the caller.

Parameters
[in,out]TokenAn access token where the logon session is about to be inserted in.
Returns
STATUS_SUCCESS is returned if the logon session has been inserted into the token successfully. STATUS_NO_SUCH_LOGON_SESSION is returned when no logon session has been found with the matching ID of the token and as such we've failed to add the logon session to the token. STATUS_INSUFFICIENT_RESOURCES is returned if memory pool allocation for the new session has failed.

Definition at line 368 of file srm.c.

370{
372 PAGED_CODE();
373
374 /* Ensure that our token is not some plain garbage */
375 ASSERT(Token);
376
377 /* Acquire the database lock */
379
380 for (LogonSession = SepLogonSessions;
381 LogonSession != NULL;
382 LogonSession = LogonSession->Next)
383 {
384 /*
385 * The insertion of a logon session into the token has to be done
386 * only IF the authentication ID of the token matches with the ID
387 * of the logon itself.
388 */
389 if (RtlEqualLuid(&LogonSession->LogonId, &Token->AuthenticationId))
390 {
391 break;
392 }
393 }
394
395 /* If we reach this then we cannot proceed further */
396 if (LogonSession == NULL)
397 {
398 DPRINT1("SepRmInsertLogonSessionIntoToken(): Couldn't insert the logon session into the specific access token!\n");
401 }
402
403 /*
404 * Allocate the session that we are going
405 * to insert it to the token.
406 */
407 Token->LogonSession = ExAllocatePoolWithTag(PagedPool,
410 if (Token->LogonSession == NULL)
411 {
412 DPRINT1("SepRmInsertLogonSessionIntoToken(): Couldn't allocate new logon session into the memory pool!\n");
415 }
416
417 /*
418 * Begin copying the logon session references data from the
419 * session whose ID matches with the token authentication ID to
420 * the new session we've allocated blocks of pool memory for it.
421 */
422 Token->LogonSession->Next = LogonSession->Next;
423 Token->LogonSession->LogonId = LogonSession->LogonId;
424 Token->LogonSession->ReferenceCount = LogonSession->ReferenceCount;
425 Token->LogonSession->Flags = LogonSession->Flags;
426 Token->LogonSession->pDeviceMap = LogonSession->pDeviceMap;
427 InsertHeadList(&LogonSession->TokenList, &Token->LogonSession->TokenList);
428
429 /* Release the database lock and we're done */
431 return STATUS_SUCCESS;
432}
#define InsertHeadList(ListHead, Entry)

Referenced by SepCreateToken(), SepDuplicateToken(), and SepPerformTokenFiltering().

◆ SepRmReferenceLogonSession()

NTSTATUS SepRmReferenceLogonSession ( _In_ PLUID  LogonLuid)

References a logon session.

Parameters
[in]LogonLuidA valid LUID that points to the logon session in the database that we're going to reference it.
Returns
Returns STATUS_SUCCESS if the logon has been referenced. STATUS_NO_SUCH_LOGON_SESSION is returned if the session couldn't be found otherwise.

Definition at line 695 of file srm.c.

697{
698 PSEP_LOGON_SESSION_REFERENCES CurrentSession;
699
700 PAGED_CODE();
701
702 DPRINT("SepRmReferenceLogonSession(%08lx:%08lx)\n",
703 LogonLuid->HighPart, LogonLuid->LowPart);
704
705 /* Acquire the database lock */
707
708 /* Loop all existing sessions */
709 for (CurrentSession = SepLogonSessions;
710 CurrentSession != NULL;
711 CurrentSession = CurrentSession->Next)
712 {
713 /* Check if the LUID matches the new one */
714 if (RtlEqualLuid(&CurrentSession->LogonId, LogonLuid))
715 {
716 /* Reference the session */
717 ++CurrentSession->ReferenceCount;
718 DPRINT("ReferenceCount: %lu\n", CurrentSession->ReferenceCount);
719
720 /* Release the database lock */
722
723 return STATUS_SUCCESS;
724 }
725 }
726
727 /* Release the database lock */
729
731}

◆ SepRmRemoveLogonSessionFromToken()

NTSTATUS NTAPI SepRmRemoveLogonSessionFromToken ( _Inout_ PTOKEN  Token)

Removes a logon session from an access token.

Parameters
[in,out]TokenAn access token whose logon session is to be removed from it.
Returns
STATUS_SUCCESS is returned if the logon session has been removed from the token successfully. STATUS_NO_SUCH_LOGON_SESSION is returned when no logon session has been found with the matching ID of the token and as such we've failed to remove the logon session from the token.

Definition at line 449 of file srm.c.

451{
453 PAGED_CODE();
454
455 /* Ensure that our token is not some plain garbage */
456 ASSERT(Token);
457
458 /* Acquire the database lock */
460
461 for (LogonSession = SepLogonSessions;
462 LogonSession != NULL;
463 LogonSession = LogonSession->Next)
464 {
465 /*
466 * Remove the logon session only when the IDs of the token and the
467 * logon match.
468 */
469 if (RtlEqualLuid(&LogonSession->LogonId, &Token->AuthenticationId))
470 {
471 break;
472 }
473 }
474
475 /* They don't match */
476 if (LogonSession == NULL)
477 {
478 DPRINT1("SepRmRemoveLogonSessionFromToken(): Couldn't remove the logon session from the access token!\n");
481 }
482
483 /* Now it's time to delete the logon session from the token */
484 RemoveEntryList(&Token->LogonSession->TokenList);
486
487 /* Release the database lock and we're done */
489 return STATUS_SUCCESS;
490}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by NtSetInformationToken(), and SepDeleteToken().

◆ SepRmSetAuditEvent()

static NTSTATUS SepRmSetAuditEvent ( _Inout_ PSEP_RM_API_MESSAGE  Message)
static

Sets an audit event for future security auditing monitoring.

Parameters
[in,out]MessageThe reference monitoring API message. It is used to determine if the right API message number is provided, RmAuditSetCommand in this case.
Returns
Returns STATUS_SUCCESS.

Definition at line 324 of file srm.c.

326{
327 ULONG i;
328 PAGED_CODE();
329
330 /* First re-initialize the bounds from the registry */
332
333 /* Make sure we have the right message and clear */
334 ASSERT(Message->ApiNumber == RmAuditSetCommand);
335 Message->ApiNumber = 0;
336
337 /* Store the enable flag in the global variable */
338 SepAdtAuditingEnabled = Message->u.SetAuditEvent.Enabled;
339
340 /* Loop all audit event types */
341 for (i = 0; i < POLICY_AUDIT_EVENT_TYPE_COUNT; i++)
342 {
343 /* Save the provided flags in the global array */
344 SeAuditingState[i] = (UCHAR)Message->u.SetAuditEvent.Flags[i];
345 }
346
347 return STATUS_SUCCESS;
348}
UCHAR SeAuditingState[POLICY_AUDIT_EVENT_TYPE_COUNT]
Definition: srm.c:59
BOOLEAN SepAdtAuditingEnabled
Definition: srm.c:54
#define POLICY_AUDIT_EVENT_TYPE_COUNT
Definition: srm.c:58
static VOID SepAdtInitializeBounds(VOID)
Initializes the local security authority audit bounds.
Definition: srm.c:274

Referenced by SepRmCommandServerThread().

◆ SeRegisterLogonSessionTerminatedRoutine()

NTSTATUS NTAPI SeRegisterLogonSessionTerminatedRoutine ( _In_ PSE_LOGON_SESSION_TERMINATED_ROUTINE  CallbackRoutine)

Registers a callback that will be called once a logon session terminates.

Parameters
[in]CallbackRoutineCallback routine address.
Returns
Returns STATUS_SUCCESS if the callback routine was registered successfully. STATUS_INVALID_PARAMETER is returned if the caller did not provide a callback routine. STATUS_INSUFFICIENT_RESOURCES is returned if the callback notification data couldn't be allocated because of lack of memory pool resources.

Definition at line 1572 of file srm.c.

1574{
1576 PAGED_CODE();
1577
1578 /* Fail, if we don not have a callback routine */
1579 if (CallbackRoutine == NULL)
1581
1582 /* Allocate a new notification item */
1586 if (Notification == NULL)
1588
1589 /* Acquire the database lock */
1591
1592 /* Set the callback routine */
1593 Notification->CallbackRoutine = CallbackRoutine;
1594
1595 /* Insert the new notification item into the list */
1598
1599 /* Release the database lock */
1601
1602 return STATUS_SUCCESS;
1603}
_Must_inspect_result_ _In_ PFLT_GET_OPERATION_STATUS_CALLBACK CallbackRoutine
Definition: fltkernel.h:1035
PSEP_LOGON_SESSION_TERMINATED_NOTIFICATION SepLogonNotifications
Definition: srm.c:63
#define TAG_LOGON_NOTIFICATION
Definition: tag.h:164
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115

◆ SeRmInitPhase0()

BOOLEAN NTAPI SeRmInitPhase0 ( VOID  )

Manages the phase 0 initialization of the security reference monitoring module of the kernel.

Returns
Returns TRUE when phase 0 initialization has completed without problems, FALSE otherwise.

Definition at line 176 of file srm.c.

177{
179
180 /* Initialize the database lock */
182
183 /* Create the system logon session */
186 {
187 return FALSE;
188 }
189
190 /* Create the anonymous logon session */
193 {
194 return FALSE;
195 }
196
197 return TRUE;
198}
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287

Referenced by SepInitializationPhase0().

◆ SeRmInitPhase1()

BOOLEAN NTAPI SeRmInitPhase1 ( VOID  )

Manages the phase 1 initialization of the security reference monitoring module of the kernel.

Returns
Returns TRUE when phase 1 initialization has completed without problems, FALSE otherwise.

Definition at line 211 of file srm.c.

212{
215 HANDLE ThreadHandle;
217
218 /* Create the SeRm command port */
219 RtlInitUnicodeString(&Name, L"\\SeRmCommandPort");
223 sizeof(ULONG),
225 2 * PAGE_SIZE);
226 if (!NT_SUCCESS(Status))
227 {
228 DPRINT1("Security: Rm Create Command Port failed 0x%lx\n", Status);
229 return FALSE;
230 }
231
232 /* Create SeLsaInitEvent */
233 RtlInitUnicodeString(&Name, L"\\SeLsaInitEvent");
235 Status = ZwCreateEvent(&SeLsaInitEvent,
239 FALSE);
240 if (!NT_VERIFY((NT_SUCCESS(Status))))
241 {
242 DPRINT1("Security: LSA init event creation failed.0x%xl\n", Status);
243 return FALSE;
244 }
245
246 /* Create the SeRm server thread */
247 Status = PsCreateSystemThread(&ThreadHandle,
249 NULL,
250 NULL,
251 NULL,
253 NULL);
254 if (!NT_SUCCESS(Status))
255 {
256 DPRINT1("Security: Rm Server Thread creation failed 0x%lx\n", Status);
257 return FALSE;
258 }
259
260 ObCloseHandle(ThreadHandle, KernelMode);
261
262 return TRUE;
263}
struct NameRec_ * Name
Definition: cdprocs.h:460
NTSYSAPI NTSTATUS NTAPI ZwCreatePort(_Out_ PHANDLE PortHandle, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _In_ ULONG MaxConnectionInfoLength, _In_ ULONG MaxMessageLength, _In_ ULONG MaxPoolUsage)
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define GENERIC_WRITE
Definition: nt_native.h:90
@ NotificationEvent
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
VOID NTAPI SepRmCommandServerThread(_In_ PVOID StartContext)
Manages the SRM server API commands, that is, receiving such API command messages from the user mode ...
Definition: srm.c:1226
#define PORT_MAXIMUM_MESSAGE_LENGTH
Definition: iotypes.h:2029

Referenced by Phase1InitializationDiscard().

◆ SeUnregisterLogonSessionTerminatedRoutine()

NTSTATUS NTAPI SeUnregisterLogonSessionTerminatedRoutine ( _In_ PSE_LOGON_SESSION_TERMINATED_ROUTINE  CallbackRoutine)

Un-registers a callback routine, previously registered by SeRegisterLogonSessionTerminatedRoutine function.

Parameters
[in]CallbackRoutineCallback routine address to un-register.
Returns
Returns STATUS_SUCCESS if the callback routine was un-registered successfully. STATUS_INVALID_PARAMETER is returned if the caller did not provide a callback routine. STATUS_NOT_FOUND is returned if the callback notification item couldn't be found.

Definition at line 1621 of file srm.c.

1623{
1626 PAGED_CODE();
1627
1628 /* Fail, if we don not have a callback routine */
1629 if (CallbackRoutine == NULL)
1631
1632 /* Acquire the database lock */
1634
1635 /* Loop all registered notification items */
1636 for (Current = SepLogonNotifications;
1637 Current != NULL;
1638 Current = Current->Next)
1639 {
1640 /* Check if the callback routine matches the provided one */
1641 if (Current->CallbackRoutine == CallbackRoutine)
1642 break;
1643
1644 Previous = Current;
1645 }
1646
1647 if (Current == NULL)
1648 {
1650 }
1651 else
1652 {
1653 /* Remove the current notification item from the list */
1654 if (Previous == NULL)
1655 SepLogonNotifications = Current->Next;
1656 else
1657 Previous->Next = Current->Next;
1658
1659 /* Free the current notification item */
1660 ExFreePoolWithTag(Current,
1662
1664 }
1665
1666 /* Release the database lock */
1668
1669 return Status;
1670}
struct _SEP_LOGON_SESSION_TERMINATED_NOTIFICATION * Next
Definition: srm.c:20
PSE_LOGON_SESSION_TERMINATED_ROUTINE CallbackRoutine
Definition: srm.c:21

Variable Documentation

◆ SeAnonymousAuthenticationId

◆ SeAuditingState

Definition at line 59 of file srm.c.

Referenced by SepRmSetAuditEvent().

◆ SeLsaInitEvent

HANDLE SeLsaInitEvent

Definition at line 46 of file srm.c.

Referenced by SepRmCommandServerThreadInit(), and SeRmInitPhase1().

◆ SepAdtAuditingEnabled

BOOLEAN SepAdtAuditingEnabled

Definition at line 54 of file srm.c.

Referenced by SepRmSetAuditEvent().

◆ SepAdtMaxListLength

ULONG SepAdtMaxListLength = 0x3000

Definition at line 56 of file srm.c.

Referenced by SepAdtInitializeBounds().

◆ SepAdtMinListLength

ULONG SepAdtMinListLength = 0x2000

Definition at line 55 of file srm.c.

Referenced by SepAdtInitializeBounds().

◆ SepCommandPortViewBase

PVOID SepCommandPortViewBase

Definition at line 48 of file srm.c.

Referenced by SepRmCommandServerThreadInit().

◆ SepCommandPortViewBaseOffset

ULONG_PTR SepCommandPortViewBaseOffset

Definition at line 50 of file srm.c.

Referenced by SepRmCommandServerThreadInit().

◆ SepCommandPortViewRemoteBase

PVOID SepCommandPortViewRemoteBase

Definition at line 49 of file srm.c.

Referenced by SepRmCommandServerThreadInit().

◆ SepLogonNotifications

◆ SepLogonSessions

◆ SepRmCommandMessagePort

HANDLE SepRmCommandMessagePort
static

Definition at line 52 of file srm.c.

Referenced by SepRmCommandServerThread(), and SepRmCommandServerThreadInit().

◆ SepRmDbLock

◆ SeRmCommandPort

HANDLE SeRmCommandPort

Definition at line 45 of file srm.c.

◆ SeSystemAuthenticationId

LUID SeSystemAuthenticationId
extern

Definition at line 20 of file token.c.

Referenced by SepCreateSystemProcessToken(), SepRmDeleteLogonSession(), and SeRmInitPhase0().