test: seastate.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# seastate.c File Reference

`#include "tokenp.h"`

Go to the source code of this file.

## Defines

#define | GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
#define | SEP_PRIVILEGE_SET_HEADER_SIZE

## Functions

NTSTATUS | SeCreateAccessState (IN PACCESS_STATE AccessState, IN PAUX_ACCESS_DATA AuxData, IN ACCESS_MASK DesiredAccess, IN PGENERIC_MAPPING GenericMapping OPTIONAL)
VOID | SeDeleteAccessState (PACCESS_STATE AccessState)
VOID | SeSetAccessStateGenericMapping (PACCESS_STATE AccessState, PGENERIC_MAPPING GenericMapping)
NTSTATUS | SeAppendPrivileges (PACCESS_STATE AccessState, PPRIVILEGE_SET Privileges)
VOID | SepConcatenatePrivileges (IN PPRIVILEGE_SET TargetPrivilegeSet, IN ULONG TargetBufferSize, IN PPRIVILEGE_SET SourcePrivilegeSet)

## Define Documentation

#define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)

| Definition at line 40 of file seastate.c.

#define SEP_PRIVILEGE_SET_HEADER_SIZE

Value:

    ((ULONG)sizeof(PRIVILEGE_SET) -     \
                    (ANYSIZE_ARRAY * (ULONG)sizeof(LUID_AND_ATTRIBUTES)))

Definition at line 49 of file seastate.c.

Referenced by SepConcatenatePrivileges().

## Function Documentation

NTSTATUS SeAppendPrivileges | ( | PACCESS_STATE | AccessState,
|  | PPRIVILEGE_SET | Privileges
| ) |

Definition at line 434 of file seastate.c.

References _ACCESS_STATE::AuxData, ExAllocatePoolWithTag, ExFreePool(), INITIAL_PRIVILEGE_COUNT, NULL, PAGED_CODE, PagedPool, _ACCESS_STATE::PrivilegesAllocated, _AUX_ACCESS_DATA::PrivilegesUsed, SepConcatenatePrivileges(), SepPrivilegeSetSize, and TRUE.

Referenced by IopCheckBackupRestorePrivilege(), IopParseDevice(), ObCheckCreateObjectAccess(), ObCheckObjectAccess(), ObpCheckTraverseAccess(), and ObpIncrementHandleCount().

    00440                    :
    00441
    00442     This routine takes a privilege set and adds it to the privilege set
    00443     imbedded in an ACCESS_STATE structure.
    00444
    00445     An AccessState may contain up to three imbedded privileges.  To
    00446     add more, this routine will allocate a block of memory, copy
    00447     the current privileges into it, and append the new privilege
    00448     to that block.  A bit is set in the AccessState indicating that
    00449     the pointer to the privilge set in the structure points to pool
    00450     memory and must be deallocated.
    00451
    00452 Arguments:
    00453
    00454     AccessState - The AccessState structure representing the current
    00455         access attempt.
    00456
    00457     Privileges - A pointer to a privilege set to be added.
    00458
    00459 Return Value:
    00460
    00461     STATUS_INSUFFICIENT_RESOURCES - an attempt to allocate pool memory
    00462         failed.
    00463
    00464 --*/
    00465
    00466 {
    00467     ULONG NewPrivilegeSetSize;
    00468     PPRIVILEGE_SET NewPrivilegeSet;
    00469     PAUX_ACCESS_DATA AuxData;
    00470
    00471     PAGED_CODE();
    00472
    00473     AuxData = (PAUX_ACCESS_DATA)AccessState->AuxData;
    00474
    00475     if (Privileges->PrivilegeCount + AuxData->PrivilegesUsed->PrivilegeCount >
    00476         INITIAL_PRIVILEGE_COUNT) {
    00477
    00478         //
    00479         // Compute the total size of the two privilege sets
    00480         //
    00481
    00482         NewPrivilegeSetSize =  SepPrivilegeSetSize( Privileges ) +
    00483                                SepPrivilegeSetSize( AuxData->PrivilegesUsed );
    00484
    00485         NewPrivilegeSet = ExAllocatePoolWithTag( PagedPool, NewPrivilegeSetSize, 'rPeS' );
    00486
    00487         if (NewPrivilegeSet == NULL) {
    00488             return( STATUS_INSUFFICIENT_RESOURCES );
    00489         }
    00490
    00491
    00492         RtlCopyMemory(
    00493             NewPrivilegeSet,
    00494             AuxData->PrivilegesUsed,
    00495             SepPrivilegeSetSize( AuxData->PrivilegesUsed )
    00496             );
    00497
    00498         //
    00499         // Note that this will adjust the privilege count in the
    00500         // structure for us.
    00501         //
    00502
    00503         SepConcatenatePrivileges(
    00504             NewPrivilegeSet,
    00505             NewPrivilegeSetSize,
    00506             Privileges
    00507             );
    00508
    00509         if (AccessState->PrivilegesAllocated) {
    00510             ExFreePool( AuxData->PrivilegesUsed );
    00511         }
    00512
    00513         AuxData->PrivilegesUsed = NewPrivilegeSet;
    00514
    00515         //
    00516         // Mark that we've allocated memory for the privilege set,
    00517         // so we know to free it when we're cleaning up.
    00518         //
    00519
    00520         AccessState->PrivilegesAllocated = TRUE;
    00521
    00522     } else {
    00523
    00524         //
    00525         // Note that this will adjust the privilege count in the
    00526         // structure for us.
    00527         //
    00528
    00529         SepConcatenatePrivileges(
    00530             AuxData->PrivilegesUsed,
    00531             sizeof(INITIAL_PRIVILEGE_SET),
    00532             Privileges
    00533             );
    00534
    00535     }
    00536
    00537     return( STATUS_SUCCESS );
    00538
    00539 }

NTSTATUS SeCreateAccessState | ( | IN PACCESS_STATE | AccessState,
|  | IN PAUX_ACCESS_DATA | AuxData,
|  | IN ACCESS_MASK | DesiredAccess,
|  | IN PGENERIC_MAPPING GenericMapping | OPTIONAL
| ) |

Definition at line 180 of file seastate.c.

References ACCESS_STATE, ASSERT, EffectiveToken, ExAllocateLocallyUniqueId, FALSE, GENERIC_ACCESS, NULL, PAGED_CODE, PTOKEN, RtlMapGenericMask(), SeCaptureSubjectContext(), and TOKEN_HAS_TRAVERSE_PRIVILEGE.

Referenced by AccessCheckObject(), NtDuplicateObject(), NtOpenProcess(), NtOpenThread(), ObInsertObject(), ObOpenObjectByName(), ObOpenObjectByPointer(), ObReferenceObjectByName(), and SepCreateToken().

    00188                    :
    00189
    00190     This routine initializes an ACCESS_STATE structure.  This consists
    00191     of:
    00192
    00193     - zeroing the entire structure
    00194
    00195     - mapping generic access types in the passed DesiredAccess
    00196     and putting it into the structure
    00197
    00198     - "capturing" the Subject Context, which must be held for the
    00199     duration of the access attempt (at least until auditing is performed).
    00200
    00201     - Allocating an Operation ID, which is an LUID that will be used
    00202     to associate different parts of the access attempt in the audit
    00203     log.
    00204
    00205 Arguments:
    00206
    00207     AccessState - a pointer to the structure to be initialized.
    00208
    00209     AuxData - Supplies a buffer big enough for an AuxData structure
    00210         so we don't have to allocate one.
    00211
    00212     DesiredAccess - Access mask containing the desired access
    00213
    00214     GenericMapping - Optionally supplies a pointer to a generic mapping
    00215         that may be used to map any generic access requests that may
    00216         have been passed in the DesiredAccess parameter.
    00217
    00218         Note that if this parameter is not supplied, it must be filled
    00219         in at some later point.  The IO system does this in IopParseDevice.
    00220
    00221 Return Value:
    00222
    00223     Error if the attempt to allocate an LUID fails.
    00224
    00225     Note that this error may be safely ignored if it is known that all
    00226     security checks will be performed with PreviousMode == KernelMode.
    00227     Know what you're doing if you choose to ignore this.
    00228
    00229 --*/
    00230
    00231 {
    00232
    00233     ACCESS_MASK MappedAccessMask;
    00234     PSECURITY_DESCRIPTOR InputSecurityDescriptor = NULL;
    00235
    00236     PAGED_CODE();
    00237
    00238     //
    00239     // Don't modify what he passed in
    00240     //
    00241
    00242     MappedAccessMask = DesiredAccess;
    00243
    00244     //
    00245     // Map generic access to object specific access iff generic access types
    00246     // are specified and a generic access mapping table is provided.
    00247     //
    00248
    00249     if ( ((DesiredAccess & GENERIC_ACCESS) != 0) &&
    00250          ARGUMENT_PRESENT(GenericMapping) ) {
    00251
    00252         RtlMapGenericMask(
    00253             &MappedAccessMask,
    00254             GenericMapping
    00255             );
    00256     }
    00257
    00258     RtlZeroMemory(AccessState, sizeof(ACCESS_STATE));
    00259
    00260     //
    00261     // Assume RtlZeroMemory has initialized these fields properly
    00262     //
    00263
    00264     ASSERT( AccessState->SecurityDescriptor == NULL );
    00265     ASSERT( AccessState->PrivilegesAllocated == FALSE );
    00266
    00267     AccessState->AuxData = AuxData;
    00268
    00269     SeCaptureSubjectContext(&AccessState->SubjectSecurityContext);
    00270
    00271     if (((PTOKEN)EffectiveToken( &AccessState->SubjectSecurityContext ))->TokenFlags & TOKEN_HAS_TRAVERSE_PRIVILEGE ) {
    00272         AccessState->Flags = TOKEN_HAS_TRAVERSE_PRIVILEGE;
    00273     }
    00274
    00275     AccessState->RemainingDesiredAccess = MappedAccessMask;
    00276     AccessState->OriginalDesiredAccess = MappedAccessMask;
    00277     AuxData->PrivilegesUsed = (PPRIVILEGE_SET)((ULONG_PTR)AccessState +
    00278                               (FIELD_OFFSET(ACCESS_STATE, Privileges)));
    00279
    00280     ExAllocateLocallyUniqueId(&AccessState->OperationID);
    00281
    00282     if (ARGUMENT_PRESENT(GenericMapping)) {
    00283         AuxData->GenericMapping = *GenericMapping;
    00284     }
    00285
    00286     return( STATUS_SUCCESS );
    00287
    00288 }

VOID SeDeleteAccessState | ( | PACCESS_STATE | AccessState | ) |

Definition at line 348 of file seastate.c.

References _ACCESS_STATE::AuxData, ExFreePool(), NULL, _ACCESS_STATE::ObjectName, _ACCESS_STATE::ObjectTypeName, PAGED_CODE, _ACCESS_STATE::PrivilegesAllocated, _AUX_ACCESS_DATA::PrivilegesUsed, SeReleaseSubjectContext(), and _ACCESS_STATE::SubjectSecurityContext.

Referenced by AccessCheckObject(), NtDuplicateObject(), NtOpenProcess(), NtOpenThread(), ObInsertObject(), ObOpenObjectByName(), ObOpenObjectByPointer(), ObReferenceObjectByName(), and SepCreateToken().

    00354                    :
    00355
    00356     This routine deallocates any memory that may have been allocated as
    00357     part of constructing the access state (normally only for an excessive
    00358     number of privileges), and frees the Subject Context.
    00359
    00360 Arguments:
    00361
    00362     AccessState - a pointer to the ACCESS_STATE structure to be
    00363         deallocated.
    00364
    00365 Return Value:
    00366
    00367     None.
    00368
    00369 --*/
    00370
    00371 {
    00372     PAUX_ACCESS_DATA AuxData;
    00373
    00374     PAGED_CODE();
    00375
    00376     AuxData = (PAUX_ACCESS_DATA)AccessState->AuxData;
    00377
    00378     if (AccessState->PrivilegesAllocated) {
    00379         ExFreePool( (PVOID)AuxData->PrivilegesUsed );
    00380     }
    00381
    00382     if (AccessState->ObjectName.Buffer != NULL) {
    00383         ExFreePool(AccessState->ObjectName.Buffer);
    00384     }
    00385
    00386     if (AccessState->ObjectTypeName.Buffer != NULL) {
    00387         ExFreePool(AccessState->ObjectTypeName.Buffer);
    00388     }
    00389
    00390     SeReleaseSubjectContext(&AccessState->SubjectSecurityContext);
    00391
    00392     return;
    00393 }

VOID SepConcatenatePrivileges | ( | IN PPRIVILEGE_SET | TargetPrivilegeSet,
|  | IN ULONG | TargetBufferSize,
|  | IN PPRIVILEGE_SET | SourcePrivilegeSet
| ) |

Definition at line 543 of file seastate.c.

References ASSERT, PAGED_CODE, SEP_PRIVILEGE_SET_HEADER_SIZE, and SepPrivilegeSetSize.

Referenced by SeAppendPrivileges().

    00551                    :
    00552
    00553     Takes two privilege sets and appends the second to the end of the
    00554     first.
    00555
    00556     There must be enough space left at the end of the first privilege
    00557     set to contain the second.
    00558
    00559 Arguments:
    00560
    00561     TargetPrivilegeSet - Supplies a buffer containing a privilege set.
    00562         The buffer must be large enough to contain the second privilege
    00563         set.
    00564
    00565     TargetBufferSize - Supplies the size of the target buffer.
    00566
    00567     SourcePrivilegeSet - Supplies the privilege set to be copied
    00568         into the target buffer.
    00569
    00570 Return Value:
    00571
    00572     None
    00573
    00574 --*/
    00575
    00576 {
    00577     PVOID Base;
    00578     PVOID Source;
    00579     ULONG Length;
    00580
    00581     PAGED_CODE();
    00582
    00583     ASSERT( ((ULONG)SepPrivilegeSetSize( TargetPrivilegeSet ) +
    00584              (ULONG)SepPrivilegeSetSize( SourcePrivilegeSet ) -
    00585              SEP_PRIVILEGE_SET_HEADER_SIZE  ) <=
    00586             TargetBufferSize
    00587           );
    00588
    00589     Base = (PVOID)((ULONG_PTR)TargetPrivilegeSet + SepPrivilegeSetSize( TargetPrivilegeSet ));
    00590
    00591     Source = (PVOID) ((ULONG_PTR)SourcePrivilegeSet + SEP_PRIVILEGE_SET_HEADER_SIZE);
    00592
    00593     Length = SourcePrivilegeSet->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES);
    00594
    00595     RtlMoveMemory(
    00596         Base,
    00597         Source,
    00598         Length
    00599         );
    00600
    00601     TargetPrivilegeSet->PrivilegeCount += SourcePrivilegeSet->PrivilegeCount;
    00602
    00603 }
    }

VOID SeSetAccessStateGenericMapping | ( | PACCESS_STATE | AccessState,
|  | PGENERIC_MAPPING | GenericMapping
| ) |

Definition at line 396 of file seastate.c.

References _ACCESS_STATE::AuxData, _AUX_ACCESS_DATA::GenericMapping, and PAGED_CODE.

Referenced by IopParseDevice().

    00403                    :
    00404
    00405     This routine sets the GenericMapping field in an AccessState structure.
    00406     It must be called before access validation is performed if the GenericMapping
    00407     is not passed in when the AccessState structure is created.
    00408
    00409 Arguments:
    00410
    00411     AccessState - a pointer to the ACCESS_STATE structure to be modified.
    00412
    00413     GenericMapping - a pointer to the GenericMapping to be copied into the AccessState.
    00414
    00415 Return Value:
    00416
    00417
    00418 --*/
    00419 {
    00420     PAUX_ACCESS_DATA AuxData;
    00421
    00422     PAGED_CODE();
    00423
    00424     AuxData = (PAUX_ACCESS_DATA)AccessState->AuxData;
    00425
    00426     AuxData->GenericMapping = *GenericMapping;
    00427
    00428     return;
    00429 }