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

seassign.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 Seassign.c 00008 00009 Abstract: 00010 00011 This Module implements the SeAssignSecurity procedure. For a description 00012 of the pool allocation strategy please see the comments in semethod.c 00013 00014 Author: 00015 00016 Gary Kimura (GaryKi) 9-Nov-1989 00017 00018 Environment: 00019 00020 Kernel Mode 00021 00022 Revision History: 00023 00024 Richard Ward (RichardW) 14-April-92 00025 Robert Reichel (RobertRe) 28-February-95 00026 Added Compound ACEs 00027 00028 --*/ 00029 00030 00031 #include "sep.h" 00032 #include "tokenp.h" 00033 #include "sertlp.h" 00034 #include "zwapi.h" 00035 #include "nturtl.h" 00036 00037 00038 // 00039 // Local macros and procedures 00040 // 00041 00042 00043 NTSTATUS 00044 SepInheritAcl ( 00045 IN PACL Acl, 00046 IN BOOLEAN IsDirectoryObject, 00047 IN PSID OwnerSid, 00048 IN PSID GroupSid, 00049 IN PSID ServerSid OPTIONAL, 00050 IN PSID ClientSid OPTIONAL, 00051 IN PGENERIC_MAPPING GenericMapping, 00052 IN POOL_TYPE PoolType, 00053 OUT PACL *NewAcl 00054 ); 00055 00056 00057 #ifdef ALLOC_PRAGMA 00058 #pragma alloc_text(PAGE,SeAssignSecurity) 00059 #pragma alloc_text(PAGE,SeAssignSecurityEx) 00060 #pragma alloc_text(PAGE,SeDeassignSecurity) 00061 #pragma alloc_text(PAGE,SepInheritAcl) 00062 #pragma alloc_text(PAGE,SeAssignWorldSecurityDescriptor) 00063 #pragma alloc_text(PAGE,SepDumpSecurityDescriptor) 00064 #pragma alloc_text(PAGE,SepPrintAcl) 00065 #pragma alloc_text(PAGE,SepPrintSid) 00066 #pragma alloc_text(PAGE,SepDumpTokenInfo) 00067 #pragma alloc_text(PAGE,SepSidTranslation) 00068 #endif 00069 00070 00071 // 00072 // These variables control whether security descriptors and token 00073 // information are dumped by their dump routines. This allows 00074 // selective turning on and off of debugging output by both program 00075 // control and via the kernel debugger. 00076 // 00077 00078 #if DBG 00079 00080 BOOLEAN SepDumpSD = FALSE; 00081 BOOLEAN SepDumpToken = FALSE; 00082 00083 #endif 00084 00085 00086 00087 00088 NTSTATUS 00089 SeAssignSecurity ( 00090 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, 00091 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, 00092 OUT PSECURITY_DESCRIPTOR *NewDescriptor, 00093 IN BOOLEAN IsDirectoryObject, 00094 IN PSECURITY_SUBJECT_CONTEXT SubjectContext, 00095 IN PGENERIC_MAPPING GenericMapping, 00096 IN POOL_TYPE PoolType 00097 ) 00098 00099 /*++ 00100 00101 Routine Description: 00102 00103 This routine assumes privilege checking HAS NOT yet been performed 00104 and so will be performed by this routine. 00105 00106 This procedure is used to build a security descriptor for a new object 00107 given the security descriptor of its parent directory and any originally 00108 requested security for the object. The final security descriptor 00109 returned to the caller may contain a mix of information, some explicitly 00110 provided other from the new object's parent. 00111 00112 00113 See RtlpNewSecurityObject for a descriptor of how the NewDescriptor is 00114 built. 00115 00116 00117 Arguments: 00118 00119 ParentDescriptor - Optionally supplies the security descriptor of the 00120 parent directory under which this new object is being created. 00121 00122 ExplicitDescriptor - Supplies the address of a pointer to the security 00123 descriptor as specified by the user that is to be applied to 00124 the new object. 00125 00126 NewDescriptor - Returns the actual security descriptor for the new 00127 object that has been modified according to above rules. 00128 00129 IsDirectoryObject - Specifies if the new object is itself a directory 00130 object. A value of TRUE indicates the object is a container of other 00131 objects. 00132 00133 SubjectContext - Supplies the security context of the subject creating the 00134 object. This is used to retrieve default security information for the 00135 new object, such as default owner, primary group, and discretionary 00136 access control. 00137 00138 GenericMapping - Supplies a pointer to an array of access mask values 00139 denoting the mapping between each generic right to non-generic rights. 00140 00141 PoolType - Specifies the pool type to use to when allocating a new 00142 security descriptor. 00143 00144 Return Value: 00145 00146 STATUS_SUCCESS - indicates the operation was successful. 00147 00148 STATUS_INVALID_OWNER - The owner SID provided as the owner of the 00149 target security descriptor is not one the caller is authorized 00150 to assign as the owner of an object. 00151 00152 STATUS_PRIVILEGE_NOT_HELD - The caller does not have the privilege 00153 necessary to explicitly assign the specified system ACL. 00154 SeSecurityPrivilege privilege is needed to explicitly assign 00155 system ACLs to objects. 00156 --*/ 00157 00158 { 00159 NTSTATUS Status; 00160 ULONG AutoInherit = 0; 00161 PAGED_CODE(); 00162 00163 #if DBG 00164 if ( ARGUMENT_PRESENT( ExplicitDescriptor) ) { 00165 SepDumpSecurityDescriptor( ExplicitDescriptor, 00166 "\nSeAssignSecurity: Input security descriptor = \n" 00167 ); 00168 } 00169 00170 if (ARGUMENT_PRESENT( ParentDescriptor )) { 00171 SepDumpSecurityDescriptor( ParentDescriptor, 00172 "\nSeAssignSecurity: Parent security descriptor = \n" 00173 ); 00174 } 00175 #endif // DBG 00176 00177 // 00178 // If the Parent SD was created via AutoInheritance, 00179 // and this object is being created with no explicit descriptor, 00180 // then we can safely create this object as AutoInherit. 00181 // 00182 00183 if ( ParentDescriptor != NULL ) { 00184 00185 if ( (ExplicitDescriptor == NULL || 00186 (((PISECURITY_DESCRIPTOR)ExplicitDescriptor)->Control & SE_DACL_PRESENT) == 0 ) && 00187 (((PISECURITY_DESCRIPTOR)ParentDescriptor)->Control & SE_DACL_AUTO_INHERITED) != 0 ) { 00188 AutoInherit |= SEF_DACL_AUTO_INHERIT; 00189 } 00190 00191 if ( (ExplicitDescriptor == NULL || 00192 (((PISECURITY_DESCRIPTOR)ExplicitDescriptor)->Control & SE_SACL_PRESENT) == 0 ) && 00193 (((PISECURITY_DESCRIPTOR)ParentDescriptor)->Control & SE_SACL_AUTO_INHERITED) != 0 ) { 00194 AutoInherit |= SEF_SACL_AUTO_INHERIT; 00195 } 00196 00197 } 00198 00199 00200 Status = RtlpNewSecurityObject ( 00201 ParentDescriptor OPTIONAL, 00202 ExplicitDescriptor OPTIONAL, 00203 NewDescriptor, 00204 NULL, // No object type 00205 IsDirectoryObject, 00206 AutoInherit, 00207 (HANDLE) SubjectContext, 00208 GenericMapping ); 00209 00210 #if DBG 00211 if ( NT_SUCCESS(Status)) { 00212 SepDumpSecurityDescriptor( *NewDescriptor, 00213 "SeAssignSecurity: Final security descriptor = \n" 00214 ); 00215 } 00216 #endif 00217 00218 return Status; 00219 00220 00221 // RtlpNewSecurityObject always uses PagedPool. 00222 UNREFERENCED_PARAMETER( PagedPool ); 00223 00224 } 00225 00226 00227 NTSTATUS 00228 SeAssignSecurityEx ( 00229 IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL, 00230 IN PSECURITY_DESCRIPTOR ExplicitDescriptor OPTIONAL, 00231 OUT PSECURITY_DESCRIPTOR *NewDescriptor, 00232 IN GUID *ObjectType OPTIONAL, 00233 IN BOOLEAN IsDirectoryObject, 00234 IN ULONG AutoInheritFlags, 00235 IN PSECURITY_SUBJECT_CONTEXT SubjectContext, 00236 IN PGENERIC_MAPPING GenericMapping, 00237 IN POOL_TYPE PoolType 00238 ) 00239 00240 /*++ 00241 00242 Routine Description: 00243 00244 This routine assumes privilege checking HAS NOT yet been performed 00245 and so will be performed by this routine. 00246 00247 This procedure is used to build a security descriptor for a new object 00248 given the security descriptor of its parent directory and any originally 00249 requested security for the object. The final security descriptor 00250 returned to the caller may contain a mix of information, some explicitly 00251 provided other from the new object's parent. 00252 00253 00254 See RtlpNewSecurityObject for a descriptor of how the NewDescriptor is 00255 built. 00256 00257 00258 Arguments: 00259 00260 ParentDescriptor - Optionally supplies the security descriptor of the 00261 parent directory under which this new object is being created. 00262 00263 ExplicitDescriptor - Supplies the address of a pointer to the security 00264 descriptor as specified by the user that is to be applied to 00265 the new object. 00266 00267 NewDescriptor - Returns the actual security descriptor for the new 00268 object that has been modified according to above rules. 00269 00270 ObjectType - GUID of the object type being created. If the object being 00271 created has no GUID associated with it, then this argument is 00272 specified as NULL. 00273 00274 IsDirectoryObject - Specifies if the new object is itself a directory 00275 object. A value of TRUE indicates the object is a container of other 00276 objects. 00277 00278 AutoInheritFlags - Controls automatic inheritance of ACES from the Parent 00279 Descriptor. Valid values are a bits mask of the logical OR of 00280 one or more of the following bits: 00281 00282 SEF_DACL_AUTO_INHERIT - If set, inherit ACEs from the 00283 DACL ParentDescriptor are inherited to NewDescriptor in addition 00284 to any explicit ACEs specified by the CreatorDescriptor. 00285 00286 SEF_SACL_AUTO_INHERIT - If set, inherit ACEs from the 00287 SACL ParentDescriptor are inherited to NewDescriptor in addition 00288 to any explicit ACEs specified by the CreatorDescriptor. 00289 00290 SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT - If set, the CreatorDescriptor 00291 is the default descriptor for ObjectType. As such, the 00292 CreatorDescriptor will be ignored if any ObjectType specific 00293 ACEs are inherited from the parent. If no such ACEs are inherited, 00294 the CreatorDescriptor is handled as though this flag were not 00295 specified. 00296 00297 SEF_AVOID_PRIVILEGE_CHECK - If set, no privilege checking is done by this 00298 routine. This flag is useful while implementing automatic inheritance 00299 to avoid checking privileges on each child updated. 00300 00301 SubjectContext - Supplies the security context of the subject creating the 00302 object. This is used to retrieve default security information for the 00303 new object, such as default owner, primary group, and discretionary 00304 access control. 00305 00306 GenericMapping - Supplies a pointer to an array of access mask values 00307 denoting the mapping between each generic right to non-generic rights. 00308 00309 PoolType - Specifies the pool type to use to when allocating a new 00310 security descriptor. 00311 00312 Return Value: 00313 00314 STATUS_SUCCESS - indicates the operation was successful. 00315 00316 STATUS_INVALID_OWNER - The owner SID provided as the owner of the 00317 target security descriptor is not one the caller is authorized 00318 to assign as the owner of an object. 00319 00320 STATUS_PRIVILEGE_NOT_HELD - The caller does not have the privilege 00321 necessary to explicitly assign the specified system ACL. 00322 SeSecurityPrivilege privilege is needed to explicitly assign 00323 system ACLs to objects. 00324 --*/ 00325 00326 { 00327 NTSTATUS Status; 00328 PAGED_CODE(); 00329 00330 #if DBG 00331 if ( ARGUMENT_PRESENT( ExplicitDescriptor) ) { 00332 SepDumpSecurityDescriptor( ExplicitDescriptor, 00333 "\nSeAssignSecurityEx: Input security descriptor = \n" 00334 ); 00335 } 00336 00337 if (ARGUMENT_PRESENT( ParentDescriptor )) { 00338 SepDumpSecurityDescriptor( ParentDescriptor, 00339 "\nSeAssignSecurityEx: Parent security descriptor = \n" 00340 ); 00341 } 00342 #endif // DBG 00343 00344 00345 Status = RtlpNewSecurityObject ( 00346 ParentDescriptor OPTIONAL, 00347 ExplicitDescriptor OPTIONAL, 00348 NewDescriptor, 00349 ObjectType, 00350 IsDirectoryObject, 00351 AutoInheritFlags, 00352 (HANDLE) SubjectContext, 00353 GenericMapping ); 00354 00355 #if DBG 00356 if ( NT_SUCCESS(Status)) { 00357 SepDumpSecurityDescriptor( *NewDescriptor, 00358 "SeAssignSecurityEx: Final security descriptor = \n" 00359 ); 00360 } 00361 #endif 00362 00363 return Status; 00364 00365 00366 // RtlpNewSecurityObject always uses PagedPool. 00367 UNREFERENCED_PARAMETER( PagedPool ); 00368 00369 } 00370 00371 00372 NTSTATUS 00373 SeDeassignSecurity ( 00374 IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor 00375 ) 00376 00377 /*++ 00378 00379 Routine Description: 00380 00381 This routine deallocates the memory associated with a security descriptor 00382 that was assigned using SeAssignSecurity. 00383 00384 00385 Arguments: 00386 00387 SecurityDescriptor - Supplies the address of a pointer to the security 00388 descriptor being deleted. 00389 00390 Return Value: 00391 00392 STATUS_SUCCESS - The deallocation was successful. 00393 00394 --*/ 00395 00396 { 00397 PAGED_CODE(); 00398 00399 if ((*SecurityDescriptor) != NULL) { 00400 ExFreePool( (*SecurityDescriptor) ); 00401 } 00402 00403 // 00404 // And zero out the pointer to it for safety sake 00405 // 00406 00407 (*SecurityDescriptor) = NULL; 00408 00409 return( STATUS_SUCCESS ); 00410 00411 } 00412 00413 00414 00415 NTSTATUS 00416 SepInheritAcl ( 00417 IN PACL Acl, 00418 IN BOOLEAN IsDirectoryObject, 00419 IN PSID ClientOwnerSid, 00420 IN PSID ClientGroupSid, 00421 IN PSID ServerOwnerSid OPTIONAL, 00422 IN PSID ServerGroupSid OPTIONAL, 00423 IN PGENERIC_MAPPING GenericMapping, 00424 IN POOL_TYPE PoolType, 00425 OUT PACL *NewAcl 00426 ) 00427 00428 /*++ 00429 00430 Routine Description: 00431 00432 This is a private routine that produces an inherited acl from 00433 a parent acl according to the rules of inheritance 00434 00435 Arguments: 00436 00437 Acl - Supplies the acl being inherited. 00438 00439 IsDirectoryObject - Specifies if the new acl is for a directory. 00440 00441 OwnerSid - Specifies the owner Sid to use. 00442 00443 GroupSid - Specifies the group SID to use. 00444 00445 ServerSid - Specifies the Server SID to use. 00446 00447 ClientSid - Specifies the Client SID to use. 00448 00449 GenericMapping - Specifies the generic mapping to use. 00450 00451 PoolType - Specifies the pool type for the new acl. 00452 00453 NewAcl - Receives a pointer to the new (inherited) acl. 00454 00455 Return Value: 00456 00457 STATUS_SUCCESS - An inheritable ACL was successfully generated. 00458 00459 STATUS_NO_INHERITANCE - An inheritable ACL was not successfully generated. 00460 This is a warning completion status. 00461 00462 STATUS_BAD_INHERITANCE_ACL - Indicates the acl built was not a valid ACL. 00463 This can becaused by a number of things. One of the more probable 00464 causes is the replacement of a CreatorId with an SID that didn't fit 00465 into the ACE or ACL. 00466 00467 STATUS_UNKNOWN_REVISION - Indicates the source ACL is a revision that 00468 is unknown to this routine. 00469 00470 --*/ 00471 00472 { 00474 // // 00475 // The logic in the ACL inheritance code must mirror the code for // 00476 // inheritance in the user mode runtime (in sertl.c). Do not make changes // 00477 // here without also making changes in that module. // 00478 // // 00480 00481 00482 NTSTATUS Status; 00483 ULONG NewAclLength; 00484 BOOLEAN NewAclExplicitlyAssigned; 00485 ULONG NewGenericControl; 00486 00487 PAGED_CODE(); 00488 ASSERT( PoolType == PagedPool ); // RtlpInheritAcl assumes paged pool 00489 00490 // 00491 // First check if the acl is null 00492 // 00493 00494 if (Acl == NULL) { 00495 00496 return STATUS_NO_INHERITANCE; 00497 } 00498 00499 // 00500 // Generating an inheritable ACL. 00501 // 00502 // Pass all parameters as though there is no auto inheritance. 00503 // 00504 00505 Status = RtlpInheritAcl( 00506 Acl, 00507 NULL, // No child ACL since no auto inheritance 00508 0, // No child control since no auto inheritance 00509 IsDirectoryObject, 00510 FALSE, // Not AutoInherit since no auto inheritance 00511 FALSE, // Not DefaultDescriptor since no auto inheritance 00512 ClientOwnerSid, 00513 ClientGroupSid, 00514 ServerOwnerSid, 00515 ServerGroupSid, 00516 GenericMapping, 00517 FALSE, // Isn't a SACL 00518 NULL, // No object GUID 00519 NewAcl, 00520 &NewAclExplicitlyAssigned, 00521 &NewGenericControl ); 00522 00523 return Status; 00524 } 00525 00526 00527 00528 NTSTATUS 00529 SeAssignWorldSecurityDescriptor( 00530 IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00531 IN OUT PULONG Length, 00532 IN PSECURITY_INFORMATION SecurityInformation 00533 ) 00534 00535 /*++ 00536 00537 Routine Description: 00538 00539 This routine is called by the I/O system to properly initialize a 00540 security descriptor for a FAT file. It will take a pointer to a 00541 buffer containing an emptry security descriptor, and create in the 00542 buffer a self-relative security descriptor with 00543 00544 Owner = WorldSid, 00545 00546 Group = WorldSid. 00547 00548 Thus, a FAT file is accessable to all. 00549 00550 Arguments: 00551 00552 SecurityDescriptor - Supplies a pointer to a buffer in which will be 00553 created a self-relative security descriptor as described above. 00554 00555 Length - The length in bytes of the buffer. If the length is too 00556 small, it will contain the minimum size required upon exit. 00557 00558 00559 Return Value: 00560 00561 STATUS_BUFFER_TOO_SMALL - The buffer was not big enough to contain 00562 the requested information. 00563 00564 00565 --*/ 00566 00567 { 00568 00569 PCHAR Field; 00570 PCHAR Base; 00571 ULONG WorldSidLength; 00572 PISECURITY_DESCRIPTOR_RELATIVE ISecurityDescriptor; 00573 ULONG MinSize; 00574 NTSTATUS Status; 00575 00576 PAGED_CODE(); 00577 00578 if ( !ARGUMENT_PRESENT( SecurityInformation )) { 00579 00580 return( STATUS_ACCESS_DENIED ); 00581 } 00582 00583 WorldSidLength = SeLengthSid( SeWorldSid ); 00584 00585 MinSize = sizeof( SECURITY_DESCRIPTOR_RELATIVE ) + 2 * WorldSidLength; 00586 00587 if ( *Length < MinSize ) { 00588 00589 *Length = MinSize; 00590 return( STATUS_BUFFER_TOO_SMALL ); 00591 } 00592 00593 *Length = MinSize; 00594 00595 ISecurityDescriptor = (SECURITY_DESCRIPTOR_RELATIVE *)SecurityDescriptor; 00596 00597 Status = RtlCreateSecurityDescriptorRelative( ISecurityDescriptor, 00598 SECURITY_DESCRIPTOR_REVISION ); 00599 00600 if (!NT_SUCCESS( Status )) { 00601 return( Status ); 00602 } 00603 00604 Base = (PCHAR)(ISecurityDescriptor); 00605 Field = Base + sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00606 00607 if ( *SecurityInformation & OWNER_SECURITY_INFORMATION ) { 00608 00609 RtlCopyMemory( Field, SeWorldSid, WorldSidLength ); 00610 ISecurityDescriptor->Owner = RtlPointerToOffset(Base,Field); 00611 Field += WorldSidLength; 00612 } 00613 00614 if ( *SecurityInformation & GROUP_SECURITY_INFORMATION ) { 00615 00616 RtlCopyMemory( Field, SeWorldSid, WorldSidLength ); 00617 ISecurityDescriptor->Group = RtlPointerToOffset(Base,Field); 00618 } 00619 00620 if ( *SecurityInformation & DACL_SECURITY_INFORMATION ) { 00621 RtlpSetControlBits( ISecurityDescriptor, SE_DACL_PRESENT ); 00622 } 00623 00624 if ( *SecurityInformation & SACL_SECURITY_INFORMATION ) { 00625 RtlpSetControlBits( ISecurityDescriptor, SE_SACL_PRESENT ); 00626 } 00627 00628 RtlpSetControlBits( ISecurityDescriptor, SE_SELF_RELATIVE ); 00629 00630 return( STATUS_SUCCESS ); 00631 00632 } 00633 00634 00635 00636 00637 00638 00639 00640 00641 // 00642 // BUGWARNING The following routines should be in a debug only kernel, since 00643 // all they do is dump stuff to a debug terminal as appropriate. The same 00644 // goes for the declarations of the variables SepDumpSD and SepDumpToken 00645 // 00646 00647 00648 00649 VOID 00650 SepDumpSecurityDescriptor( 00651 IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00652 IN PSZ TitleString 00653 ) 00654 00655 /*++ 00656 00657 Routine Description: 00658 00659 Private routine to dump a security descriptor to the debug 00660 screen. 00661 00662 Arguments: 00663 00664 SecurityDescriptor - Supplies the security descriptor to be dumped. 00665 00666 TitleString - A null terminated string to print before dumping 00667 the security descriptor. 00668 00669 00670 Return Value: 00671 00672 None. 00673 00674 00675 --*/ 00676 { 00677 #if DBG 00678 PISECURITY_DESCRIPTOR ISecurityDescriptor; 00679 UCHAR Revision; 00680 SECURITY_DESCRIPTOR_CONTROL Control; 00681 PSID Owner; 00682 PSID Group; 00683 PACL Sacl; 00684 PACL Dacl; 00685 00686 PAGED_CODE(); 00687 00688 00689 if (!SepDumpSD) { 00690 return; 00691 } 00692 00693 if (!ARGUMENT_PRESENT( SecurityDescriptor )) { 00694 return; 00695 } 00696 00697 DbgPrint(TitleString); 00698 00699 ISecurityDescriptor = ( PISECURITY_DESCRIPTOR )SecurityDescriptor; 00700 00701 Revision = ISecurityDescriptor->Revision; 00702 Control = ISecurityDescriptor->Control; 00703 00704 Owner = RtlpOwnerAddrSecurityDescriptor( ISecurityDescriptor ); 00705 Group = RtlpGroupAddrSecurityDescriptor( ISecurityDescriptor ); 00706 Sacl = RtlpSaclAddrSecurityDescriptor( ISecurityDescriptor ); 00707 Dacl = RtlpDaclAddrSecurityDescriptor( ISecurityDescriptor ); 00708 00709 DbgPrint("\nSECURITY DESCRIPTOR\n"); 00710 00711 DbgPrint("Revision = %d\n",Revision); 00712 00713 // 00714 // Print control info 00715 // 00716 00717 if (Control & SE_OWNER_DEFAULTED) { 00718 DbgPrint("Owner defaulted\n"); 00719 } 00720 if (Control & SE_GROUP_DEFAULTED) { 00721 DbgPrint("Group defaulted\n"); 00722 } 00723 if (Control & SE_DACL_PRESENT) { 00724 DbgPrint("Dacl present\n"); 00725 } 00726 if (Control & SE_DACL_DEFAULTED) { 00727 DbgPrint("Dacl defaulted\n"); 00728 } 00729 if (Control & SE_SACL_PRESENT) { 00730 DbgPrint("Sacl present\n"); 00731 } 00732 if (Control & SE_SACL_DEFAULTED) { 00733 DbgPrint("Sacl defaulted\n"); 00734 } 00735 if (Control & SE_SELF_RELATIVE) { 00736 DbgPrint("Self relative\n"); 00737 } 00738 if (Control & SE_DACL_UNTRUSTED) { 00739 DbgPrint("Dacl untrusted\n"); 00740 } 00741 if (Control & SE_SERVER_SECURITY) { 00742 DbgPrint("Server security\n"); 00743 } 00744 00745 DbgPrint("Owner "); 00746 SepPrintSid( Owner ); 00747 00748 DbgPrint("Group "); 00749 SepPrintSid( Group ); 00750 00751 DbgPrint("Sacl"); 00752 SepPrintAcl( Sacl ); 00753 00754 DbgPrint("Dacl"); 00755 SepPrintAcl( Dacl ); 00756 #endif 00757 } 00758 00759 00760 00761 VOID 00762 SepPrintAcl ( 00763 IN PACL Acl 00764 ) 00765 00766 /*++ 00767 00768 Routine Description: 00769 00770 This routine dumps via (DbgPrint) an Acl for debug purposes. It is 00771 specialized to dump standard aces. 00772 00773 Arguments: 00774 00775 Acl - Supplies the Acl to dump 00776 00777 Return Value: 00778 00779 None 00780 00781 --*/ 00782 00783 00784 { 00785 #if DBG 00786 ULONG i; 00787 PKNOWN_ACE Ace; 00788 BOOLEAN KnownType; 00789 00790 PAGED_CODE(); 00791 00792 DbgPrint("@ %8lx\n", Acl); 00793 00794 // 00795 // Check if the Acl is null 00796 // 00797 00798 if (Acl == NULL) { 00799 00800 return; 00801 00802 } 00803 00804 // 00805 // Dump the Acl header 00806 // 00807 00808 DbgPrint(" Revision: %02x", Acl->AclRevision); 00809 DbgPrint(" Size: %04x", Acl->AclSize); 00810 DbgPrint(" AceCount: %04x\n", Acl->AceCount); 00811 00812 // 00813 // Now for each Ace we want do dump it 00814 // 00815 00816 for (i = 0, Ace = FirstAce(Acl); 00817 i < Acl->AceCount; 00818 i++, Ace = NextAce(Ace) ) { 00819 00820 // 00821 // print out the ace header 00822 // 00823 00824 DbgPrint("\n AceHeader: %08lx ", *(PULONG)Ace); 00825 00826 // 00827 // special case on the standard ace types 00828 // 00829 00830 if ((Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) || 00831 (Ace->Header.AceType == ACCESS_DENIED_ACE_TYPE) || 00832 (Ace->Header.AceType == SYSTEM_AUDIT_ACE_TYPE) || 00833 (Ace->Header.AceType == SYSTEM_ALARM_ACE_TYPE) || 00834 (Ace->Header.AceType == ACCESS_ALLOWED_COMPOUND_ACE_TYPE)) { 00835 00836 // 00837 // The following array is indexed by ace types and must 00838 // follow the allowed, denied, audit, alarm seqeuence 00839 // 00840 00841 PCHAR AceTypes[] = { "Access Allowed", 00842 "Access Denied ", 00843 "System Audit ", 00844 "System Alarm ", 00845 "Compound Grant", 00846 }; 00847 00848 DbgPrint(AceTypes[Ace->Header.AceType]); 00849 DbgPrint("\n Access Mask: %08lx ", Ace->Mask); 00850 KnownType = TRUE; 00851 00852 } else { 00853 00854 DbgPrint(" Unknown Ace Type\n"); 00855 KnownType = FALSE; 00856 } 00857 00858 DbgPrint("\n"); 00859 00860 DbgPrint(" AceSize = %d\n",Ace->Header.AceSize); 00861 00862 DbgPrint(" Ace Flags = "); 00863 if (Ace->Header.AceFlags & OBJECT_INHERIT_ACE) { 00864 DbgPrint("OBJECT_INHERIT_ACE\n"); 00865 DbgPrint(" "); 00866 } 00867 00868 if (Ace->Header.AceFlags & CONTAINER_INHERIT_ACE) { 00869 DbgPrint("CONTAINER_INHERIT_ACE\n"); 00870 DbgPrint(" "); 00871 } 00872 00873 if (Ace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE) { 00874 DbgPrint("NO_PROPAGATE_INHERIT_ACE\n"); 00875 DbgPrint(" "); 00876 } 00877 00878 if (Ace->Header.AceFlags & INHERIT_ONLY_ACE) { 00879 DbgPrint("INHERIT_ONLY_ACE\n"); 00880 DbgPrint(" "); 00881 } 00882 00883 00884 if (Ace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG) { 00885 DbgPrint("SUCCESSFUL_ACCESS_ACE_FLAG\n"); 00886 DbgPrint(" "); 00887 } 00888 00889 if (Ace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG) { 00890 DbgPrint("FAILED_ACCESS_ACE_FLAG\n"); 00891 DbgPrint(" "); 00892 } 00893 00894 DbgPrint("\n"); 00895 00896 if (KnownType != TRUE) { 00897 continue; 00898 } 00899 00900 if (Ace->Header.AceType != ACCESS_ALLOWED_COMPOUND_ACE_TYPE) { 00901 DbgPrint(" Sid = "); 00902 SepPrintSid(&Ace->SidStart); 00903 } else { 00904 DbgPrint(" Server Sid = "); 00905 SepPrintSid(RtlCompoundAceServerSid(Ace)); 00906 DbgPrint("\n Client Sid = "); 00907 SepPrintSid(RtlCompoundAceClientSid( Ace )); 00908 } 00909 } 00910 #endif 00911 } 00912 00913 00914 00915 VOID 00916 SepPrintSid( 00917 IN PSID Sid 00918 ) 00919 00920 /*++ 00921 00922 Routine Description: 00923 00924 Prints a formatted Sid 00925 00926 Arguments: 00927 00928 Sid - Provides a pointer to the sid to be printed. 00929 00930 00931 Return Value: 00932 00933 None. 00934 00935 --*/ 00936 00937 { 00938 #if DBG 00939 UCHAR i; 00940 ULONG Tmp; 00941 PISID ISid; 00942 STRING AccountName; 00943 UCHAR Buffer[128]; 00944 00945 PAGED_CODE(); 00946 00947 if (Sid == NULL) { 00948 DbgPrint("Sid is NULL\n"); 00949 return; 00950 } 00951 00952 Buffer[0] = 0; 00953 00954 AccountName.MaximumLength = 127; 00955 AccountName.Length = 0; 00956 AccountName.Buffer = (PVOID)&Buffer[0]; 00957 00958 if (SepSidTranslation( Sid, &AccountName )) { 00959 00960 DbgPrint("%s ", AccountName.Buffer ); 00961 } 00962 00963 ISid = (PISID)Sid; 00964 00965 DbgPrint("S-%lu-", (USHORT)ISid->Revision ); 00966 if ( (ISid->IdentifierAuthority.Value[0] != 0) || 00967 (ISid->IdentifierAuthority.Value[1] != 0) ){ 00968 DbgPrint("0x%02hx%02hx%02hx%02hx%02hx%02hx", 00969 (USHORT)ISid->IdentifierAuthority.Value[0], 00970 (USHORT)ISid->IdentifierAuthority.Value[1], 00971 (USHORT)ISid->IdentifierAuthority.Value[2], 00972 (USHORT)ISid->IdentifierAuthority.Value[3], 00973 (USHORT)ISid->IdentifierAuthority.Value[4], 00974 (USHORT)ISid->IdentifierAuthority.Value[5] ); 00975 } else { 00976 Tmp = (ULONG)ISid->IdentifierAuthority.Value[5] + 00977 (ULONG)(ISid->IdentifierAuthority.Value[4] << 8) + 00978 (ULONG)(ISid->IdentifierAuthority.Value[3] << 16) + 00979 (ULONG)(ISid->IdentifierAuthority.Value[2] << 24); 00980 DbgPrint("%lu", Tmp); 00981 } 00982 00983 00984 for (i=0;i<ISid->SubAuthorityCount ;i++ ) { 00985 DbgPrint("-%lu", ISid->SubAuthority[i]); 00986 } 00987 DbgPrint("\n"); 00988 #endif 00989 } 00990 00991 00992 00993 00994 VOID 00995 SepDumpTokenInfo( 00996 IN PACCESS_TOKEN Token 00997 ) 00998 00999 /*++ 01000 01001 Routine Description: 01002 01003 Prints interesting information in a token. 01004 01005 Arguments: 01006 01007 Token - Provides the token to be examined. 01008 01009 01010 Return Value: 01011 01012 None. 01013 01014 --*/ 01015 01016 { 01017 #if DBG 01018 ULONG UserAndGroupCount; 01019 PSID_AND_ATTRIBUTES TokenSid; 01020 ULONG i; 01021 PTOKEN IToken; 01022 01023 PAGED_CODE(); 01024 01025 if (!SepDumpToken) { 01026 return; 01027 } 01028 01029 IToken = (TOKEN *)Token; 01030 01031 UserAndGroupCount = IToken->UserAndGroupCount; 01032 01033 DbgPrint("\n\nToken Address=%lx\n",IToken); 01034 DbgPrint("Token User and Groups Array:\n\n"); 01035 01036 for ( i = 0 , TokenSid = IToken->UserAndGroups; 01037 i < UserAndGroupCount ; 01038 i++, TokenSid++ 01039 ) { 01040 01041 SepPrintSid( TokenSid->Sid ); 01042 01043 } 01044 01045 if ( IToken->RestrictedSids ) { 01046 UserAndGroupCount = IToken->RestrictedSidCount; 01047 01048 DbgPrint("Restricted Sids Array:\n\n"); 01049 01050 for ( i = 0 , TokenSid = IToken->RestrictedSids; 01051 i < UserAndGroupCount ; 01052 i++, TokenSid++ 01053 ) { 01054 01055 SepPrintSid( TokenSid->Sid ); 01056 01057 } 01058 } 01059 #endif 01060 } 01061 01062 01063 01064 BOOLEAN 01065 SepSidTranslation( 01066 PSID Sid, 01067 PSTRING AccountName 01068 ) 01069 01070 /*++ 01071 01072 Routine Description: 01073 01074 This routine translates well-known SIDs into English names. 01075 01076 Arguments: 01077 01078 Sid - Provides the sid to be examined. 01079 01080 AccountName - Provides a string buffer in which to place the 01081 translated name. 01082 01083 Return Value: 01084 01085 None 01086 01087 --*/ 01088 01089 // AccountName is expected to have a large maximum length 01090 01091 { 01092 PAGED_CODE(); 01093 01094 if (RtlEqualSid(Sid, SeWorldSid)) { 01095 RtlInitString( AccountName, "WORLD "); 01096 return(TRUE); 01097 } 01098 01099 if (RtlEqualSid(Sid, SeLocalSid)) { 01100 RtlInitString( AccountName, "LOCAL "); 01101 return(TRUE); 01102 } 01103 01104 if (RtlEqualSid(Sid, SeNetworkSid)) { 01105 RtlInitString( AccountName, "NETWORK "); 01106 return(TRUE); 01107 } 01108 01109 if (RtlEqualSid(Sid, SeBatchSid)) { 01110 RtlInitString( AccountName, "BATCH "); 01111 return(TRUE); 01112 } 01113 01114 if (RtlEqualSid(Sid, SeInteractiveSid)) { 01115 RtlInitString( AccountName, "INTERACTIVE "); 01116 return(TRUE); 01117 } 01118 01119 if (RtlEqualSid(Sid, SeLocalSystemSid)) { 01120 RtlInitString( AccountName, "SYSTEM "); 01121 return(TRUE); 01122 } 01123 01124 if (RtlEqualSid(Sid, SeCreatorOwnerSid)) { 01125 RtlInitString( AccountName, "CREATOR_OWNER "); 01126 return(TRUE); 01127 } 01128 01129 if (RtlEqualSid(Sid, SeCreatorGroupSid)) { 01130 RtlInitString( AccountName, "CREATOR_GROUP "); 01131 return(TRUE); 01132 } 01133 01134 if (RtlEqualSid(Sid, SeCreatorOwnerServerSid)) { 01135 RtlInitString( AccountName, "CREATOR_OWNER_SERVER "); 01136 return(TRUE); 01137 } 01138 01139 if (RtlEqualSid(Sid, SeCreatorGroupServerSid)) { 01140 RtlInitString( AccountName, "CREATOR_GROUP_SERVER "); 01141 return(TRUE); 01142 } 01143 01144 return(FALSE); 01145 } 01146 01147 // 01148 // End debug only routines 01149 //

Generated on Sat May 15 19:41:43 2004 for test by doxygen 1.3.7