Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensd.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS system libraries 00004 * PURPOSE: Security descriptor functions 00005 * FILE: lib/rtl/sd.c 00006 * PROGRAMER: David Welch <welch@cwcom.net> 00007 */ 00008 00009 /* INCLUDES *****************************************************************/ 00010 00011 #include <rtl.h> 00012 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* FUNCTIONS ***************************************************************/ 00017 00018 00019 static VOID 00020 RtlpQuerySecurityDescriptorPointers(IN PISECURITY_DESCRIPTOR SecurityDescriptor, 00021 OUT PSID *Owner OPTIONAL, 00022 OUT PSID *Group OPTIONAL, 00023 OUT PACL *Sacl OPTIONAL, 00024 OUT PACL *Dacl OPTIONAL) 00025 { 00026 if (SecurityDescriptor->Control & SE_SELF_RELATIVE) 00027 { 00028 PISECURITY_DESCRIPTOR_RELATIVE RelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor; 00029 if(Owner != NULL) 00030 { 00031 *Owner = ((RelSD->Owner != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Owner) : NULL); 00032 } 00033 if(Group != NULL) 00034 { 00035 *Group = ((RelSD->Group != 0) ? (PSID)((ULONG_PTR)RelSD + RelSD->Group) : NULL); 00036 } 00037 if(Sacl != NULL) 00038 { 00039 *Sacl = (((RelSD->Control & SE_SACL_PRESENT) && (RelSD->Sacl != 0)) ? 00040 (PSID)((ULONG_PTR)RelSD + RelSD->Sacl) : NULL); 00041 } 00042 if(Dacl != NULL) 00043 { 00044 *Dacl = (((RelSD->Control & SE_DACL_PRESENT) && (RelSD->Dacl != 0)) ? 00045 (PSID)((ULONG_PTR)RelSD + RelSD->Dacl) : NULL); 00046 } 00047 } 00048 else 00049 { 00050 if(Owner != NULL) 00051 { 00052 *Owner = SecurityDescriptor->Owner; 00053 } 00054 if(Group != NULL) 00055 { 00056 *Group = SecurityDescriptor->Group; 00057 } 00058 if(Sacl != NULL) 00059 { 00060 *Sacl = ((SecurityDescriptor->Control & SE_SACL_PRESENT) ? SecurityDescriptor->Sacl : NULL); 00061 } 00062 if(Dacl != NULL) 00063 { 00064 *Dacl = ((SecurityDescriptor->Control & SE_DACL_PRESENT) ? SecurityDescriptor->Dacl : NULL); 00065 } 00066 } 00067 } 00068 00069 static VOID 00070 RtlpQuerySecurityDescriptor(PISECURITY_DESCRIPTOR SecurityDescriptor, 00071 PSID* Owner, 00072 PULONG OwnerLength, 00073 PSID* Group, 00074 PULONG GroupLength, 00075 PACL* Dacl, 00076 PULONG DaclLength, 00077 PACL* Sacl, 00078 PULONG SaclLength) 00079 { 00080 RtlpQuerySecurityDescriptorPointers(SecurityDescriptor, 00081 Owner, 00082 Group, 00083 Sacl, 00084 Dacl); 00085 00086 if (Owner != NULL) 00087 { 00088 *OwnerLength = ((*Owner != NULL) ? ROUND_UP(RtlLengthSid(*Owner), 4) : 0); 00089 } 00090 00091 if (Group != NULL) 00092 { 00093 *GroupLength = ((*Group != NULL) ? ROUND_UP(RtlLengthSid(*Group), 4) : 0); 00094 } 00095 00096 if (Dacl != NULL) 00097 { 00098 *DaclLength = ((*Dacl != NULL) ? ROUND_UP((*Dacl)->AclSize, 4) : 0); 00099 } 00100 00101 if (Sacl != NULL) 00102 { 00103 *SaclLength = ((*Sacl != NULL) ? ROUND_UP((*Sacl)->AclSize, 4) : 0); 00104 } 00105 } 00106 00107 /* 00108 * @implemented 00109 */ 00110 NTSTATUS NTAPI 00111 RtlCreateSecurityDescriptor(OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00112 IN ULONG Revision) 00113 { 00114 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00115 00116 PAGED_CODE_RTL(); 00117 00118 if (Revision != SECURITY_DESCRIPTOR_REVISION1) 00119 { 00120 return STATUS_UNKNOWN_REVISION; 00121 } 00122 00123 pSD->Revision = SECURITY_DESCRIPTOR_REVISION1; 00124 pSD->Sbz1 = 0; 00125 pSD->Control = 0; 00126 pSD->Owner = NULL; 00127 pSD->Group = NULL; 00128 pSD->Sacl = NULL; 00129 pSD->Dacl = NULL; 00130 00131 return STATUS_SUCCESS; 00132 } 00133 00134 /* 00135 * @implemented 00136 */ 00137 NTSTATUS NTAPI 00138 RtlCopySecurityDescriptor(IN PSECURITY_DESCRIPTOR pSourceSecurityDescriptor, 00139 OUT PSECURITY_DESCRIPTOR pDestinationSecurityDescriptor) 00140 { 00141 PSID Owner = NULL, Group = NULL; 00142 PACL Dacl = NULL, Sacl = NULL; 00143 BOOLEAN Defaulted, Present; 00144 DWORD OwnerLength, GroupLength; 00145 PISECURITY_DESCRIPTOR srcSD = pSourceSecurityDescriptor; 00146 PISECURITY_DESCRIPTOR destSD = pDestinationSecurityDescriptor; 00147 00148 if (srcSD->Revision != SECURITY_DESCRIPTOR_REVISION) 00149 return STATUS_UNKNOWN_REVISION; 00150 00151 /* Copy non relative dependent data */ 00152 destSD->Revision = srcSD->Revision; 00153 destSD->Sbz1 = srcSD->Sbz1; 00154 destSD->Control = srcSD->Control; 00155 00156 /* Read relative data */ 00157 RtlGetOwnerSecurityDescriptor(srcSD, &Owner, &Defaulted); 00158 OwnerLength = RtlLengthSid(Owner); 00159 RtlGetGroupSecurityDescriptor(srcSD, &Group, &Defaulted); 00160 GroupLength = RtlLengthSid(Group); 00161 RtlGetDaclSecurityDescriptor(srcSD, &Present, &Dacl, &Defaulted); 00162 RtlGetSaclSecurityDescriptor(srcSD, &Present, &Sacl, &Defaulted); 00163 00164 if (srcSD->Control & SE_SELF_RELATIVE) 00165 { 00166 destSD->Owner = srcSD->Owner; 00167 RtlCopySid(OwnerLength, (LPBYTE)destSD + (DWORD_PTR)destSD->Owner, Owner); 00168 00169 destSD->Group = srcSD->Group; 00170 RtlCopySid(GroupLength, (LPBYTE)destSD + (DWORD_PTR)destSD->Group, Group); 00171 00172 if (srcSD->Control & SE_DACL_PRESENT) 00173 { 00174 destSD->Dacl = srcSD->Dacl; 00175 00176 if(srcSD->Dacl != NULL && RtlValidAcl(srcSD->Dacl)) 00177 { 00178 RtlCopyMemory(((LPBYTE)destSD + (DWORD_PTR)destSD->Dacl), Dacl, Dacl->AclSize); 00179 } 00180 } 00181 00182 if (srcSD->Control & SE_SACL_PRESENT) 00183 { 00184 destSD->Sacl = srcSD->Sacl; 00185 00186 if(srcSD->Sacl != NULL && RtlValidAcl(srcSD->Sacl)) 00187 { 00188 RtlCopyMemory(((LPBYTE)destSD + (DWORD_PTR)destSD->Sacl), Sacl, Sacl->AclSize); 00189 } 00190 } 00191 } 00192 else 00193 { 00194 RtlCopySid(OwnerLength, destSD->Owner, Owner); 00195 RtlCopySid(GroupLength, destSD->Group, Group); 00196 00197 if (srcSD->Control & SE_DACL_PRESENT) 00198 { 00199 destSD->Dacl = RtlAllocateHeap(RtlGetProcessHeap(), 0, Dacl->AclSize); 00200 00201 if(srcSD->Dacl != NULL && RtlValidAcl(srcSD->Dacl)) 00202 { 00203 RtlCopyMemory(destSD->Dacl, Dacl, Dacl->AclSize); 00204 } 00205 } 00206 00207 if (srcSD->Control & SE_SACL_PRESENT) 00208 { 00209 destSD->Sacl = RtlAllocateHeap(RtlGetProcessHeap(), 0, Sacl->AclSize); 00210 00211 if(srcSD->Sacl != NULL && RtlValidAcl(srcSD->Sacl)) 00212 { 00213 RtlCopyMemory(destSD->Sacl, Sacl, Sacl->AclSize); 00214 } 00215 } 00216 } 00217 00218 return STATUS_SUCCESS; 00219 } 00220 00221 00222 NTSTATUS NTAPI 00223 RtlCreateSecurityDescriptorRelative (OUT PISECURITY_DESCRIPTOR_RELATIVE SecurityDescriptor, 00224 IN ULONG Revision) 00225 { 00226 PAGED_CODE_RTL(); 00227 00228 if (Revision != SECURITY_DESCRIPTOR_REVISION1) 00229 { 00230 return STATUS_UNKNOWN_REVISION; 00231 } 00232 00233 SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION1; 00234 SecurityDescriptor->Sbz1 = 0; 00235 SecurityDescriptor->Control = SE_SELF_RELATIVE; 00236 SecurityDescriptor->Owner = 0; 00237 SecurityDescriptor->Group = 0; 00238 SecurityDescriptor->Sacl = 0; 00239 SecurityDescriptor->Dacl = 0; 00240 00241 return STATUS_SUCCESS; 00242 } 00243 00244 00245 /* 00246 * @implemented 00247 */ 00248 ULONG NTAPI 00249 RtlLengthSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor) 00250 { 00251 PSID Owner, Group; 00252 PACL Sacl, Dacl; 00253 ULONG Length; 00254 00255 PAGED_CODE_RTL(); 00256 00257 if (((PISECURITY_DESCRIPTOR)SecurityDescriptor)->Control & SE_SELF_RELATIVE) 00258 Length = sizeof(SECURITY_DESCRIPTOR_RELATIVE); 00259 else 00260 Length = sizeof(SECURITY_DESCRIPTOR); 00261 00262 RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR)SecurityDescriptor, 00263 &Owner, 00264 &Group, 00265 &Sacl, 00266 &Dacl); 00267 00268 if (Owner != NULL) 00269 { 00270 Length += ROUND_UP(RtlLengthSid(Owner), 4); 00271 } 00272 00273 if (Group != NULL) 00274 { 00275 Length += ROUND_UP(RtlLengthSid(Group), 4); 00276 } 00277 00278 if (Dacl != NULL) 00279 { 00280 Length += ROUND_UP(Dacl->AclSize, 4); 00281 } 00282 00283 if (Sacl != NULL) 00284 { 00285 Length += ROUND_UP(Sacl->AclSize, 4); 00286 } 00287 00288 return Length; 00289 } 00290 00291 00292 /* 00293 * @implemented 00294 */ 00295 NTSTATUS NTAPI 00296 RtlGetDaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00297 OUT PBOOLEAN DaclPresent, 00298 OUT PACL* Dacl, 00299 OUT PBOOLEAN DaclDefaulted) 00300 { 00301 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00302 00303 PAGED_CODE_RTL(); 00304 00305 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00306 { 00307 return STATUS_UNKNOWN_REVISION; 00308 } 00309 00310 if (!(pSD->Control & SE_DACL_PRESENT)) 00311 { 00312 *DaclPresent = FALSE; 00313 return STATUS_SUCCESS; 00314 } 00315 *DaclPresent = TRUE; 00316 00317 RtlpQuerySecurityDescriptorPointers(pSD, 00318 NULL, 00319 NULL, 00320 NULL, 00321 Dacl); 00322 00323 *DaclDefaulted = ((pSD->Control & SE_DACL_DEFAULTED) ? TRUE : FALSE); 00324 00325 return STATUS_SUCCESS; 00326 } 00327 00328 00329 /* 00330 * @implemented 00331 */ 00332 NTSTATUS NTAPI 00333 RtlSetDaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00334 IN BOOLEAN DaclPresent, 00335 IN PACL Dacl, 00336 IN BOOLEAN DaclDefaulted) 00337 { 00338 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00339 00340 PAGED_CODE_RTL(); 00341 00342 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00343 { 00344 return STATUS_UNKNOWN_REVISION; 00345 } 00346 00347 if (pSD->Control & SE_SELF_RELATIVE) 00348 { 00349 return STATUS_BAD_DESCRIPTOR_FORMAT; 00350 } 00351 00352 if (!DaclPresent) 00353 { 00354 pSD->Control = pSD->Control & ~(SE_DACL_PRESENT); 00355 return STATUS_SUCCESS; 00356 } 00357 00358 pSD->Dacl = Dacl; 00359 pSD->Control |= SE_DACL_PRESENT; 00360 pSD->Control &= ~(SE_DACL_DEFAULTED); 00361 00362 if (DaclDefaulted) 00363 { 00364 pSD->Control |= SE_DACL_DEFAULTED; 00365 } 00366 00367 return STATUS_SUCCESS; 00368 } 00369 00370 00371 /* 00372 * @implemented 00373 */ 00374 BOOLEAN NTAPI 00375 RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor) 00376 { 00377 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00378 PSID Owner, Group; 00379 PACL Sacl, Dacl; 00380 00381 PAGED_CODE_RTL(); 00382 00383 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00384 { 00385 return FALSE; 00386 } 00387 00388 RtlpQuerySecurityDescriptorPointers(pSD, 00389 &Owner, 00390 &Group, 00391 &Sacl, 00392 &Dacl); 00393 00394 if ((Owner != NULL && !RtlValidSid(Owner)) || 00395 (Group != NULL && !RtlValidSid(Group)) || 00396 (Sacl != NULL && !RtlValidAcl(Sacl)) || 00397 (Dacl != NULL && !RtlValidAcl(Dacl))) 00398 { 00399 return FALSE; 00400 } 00401 00402 return TRUE; 00403 } 00404 00405 00406 /* 00407 * @implemented 00408 */ 00409 NTSTATUS NTAPI 00410 RtlSetOwnerSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00411 IN PSID Owner, 00412 IN BOOLEAN OwnerDefaulted) 00413 { 00414 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00415 00416 PAGED_CODE_RTL(); 00417 00418 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00419 { 00420 return STATUS_UNKNOWN_REVISION; 00421 } 00422 00423 if (pSD->Control & SE_SELF_RELATIVE) 00424 { 00425 return STATUS_BAD_DESCRIPTOR_FORMAT; 00426 } 00427 00428 pSD->Owner = Owner; 00429 pSD->Control &= ~(SE_OWNER_DEFAULTED); 00430 00431 if (OwnerDefaulted) 00432 { 00433 pSD->Control |= SE_OWNER_DEFAULTED; 00434 } 00435 00436 return STATUS_SUCCESS; 00437 } 00438 00439 00440 /* 00441 * @implemented 00442 */ 00443 NTSTATUS NTAPI 00444 RtlGetOwnerSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00445 OUT PSID* Owner, 00446 OUT PBOOLEAN OwnerDefaulted) 00447 { 00448 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00449 00450 PAGED_CODE_RTL(); 00451 00452 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00453 { 00454 return STATUS_UNKNOWN_REVISION; 00455 } 00456 00457 RtlpQuerySecurityDescriptorPointers(pSD, 00458 Owner, 00459 NULL, 00460 NULL, 00461 NULL); 00462 00463 *OwnerDefaulted = ((pSD->Control & SE_OWNER_DEFAULTED) ? TRUE : FALSE); 00464 00465 return STATUS_SUCCESS; 00466 } 00467 00468 00469 /* 00470 * @implemented 00471 */ 00472 NTSTATUS NTAPI 00473 RtlSetGroupSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00474 IN PSID Group, 00475 IN BOOLEAN GroupDefaulted) 00476 { 00477 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00478 00479 PAGED_CODE_RTL(); 00480 00481 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00482 { 00483 return STATUS_UNKNOWN_REVISION; 00484 } 00485 00486 if (pSD->Control & SE_SELF_RELATIVE) 00487 { 00488 return STATUS_BAD_DESCRIPTOR_FORMAT; 00489 } 00490 00491 pSD->Group = Group; 00492 pSD->Control &= ~(SE_GROUP_DEFAULTED); 00493 if (GroupDefaulted) 00494 { 00495 pSD->Control |= SE_GROUP_DEFAULTED; 00496 } 00497 00498 return STATUS_SUCCESS; 00499 } 00500 00501 00502 /* 00503 * @implemented 00504 */ 00505 NTSTATUS NTAPI 00506 RtlGetGroupSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00507 OUT PSID* Group, 00508 OUT PBOOLEAN GroupDefaulted) 00509 { 00510 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00511 00512 PAGED_CODE_RTL(); 00513 00514 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00515 { 00516 return STATUS_UNKNOWN_REVISION; 00517 } 00518 00519 RtlpQuerySecurityDescriptorPointers(pSD, 00520 NULL, 00521 Group, 00522 NULL, 00523 NULL); 00524 00525 *GroupDefaulted = ((pSD->Control & SE_GROUP_DEFAULTED) ? TRUE : FALSE); 00526 00527 return STATUS_SUCCESS; 00528 } 00529 00530 00531 /* 00532 * @implemented 00533 */ 00534 NTSTATUS NTAPI 00535 RtlMakeSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSD, 00536 OUT PSECURITY_DESCRIPTOR SelfRelativeSD, 00537 IN OUT PULONG BufferLength) 00538 { 00539 PSID Owner; 00540 PSID Group; 00541 PACL Sacl; 00542 PACL Dacl; 00543 ULONG OwnerLength; 00544 ULONG GroupLength; 00545 ULONG SaclLength; 00546 ULONG DaclLength; 00547 ULONG TotalLength; 00548 ULONG_PTR Current; 00549 PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSD; 00550 PISECURITY_DESCRIPTOR_RELATIVE pRelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD; 00551 00552 PAGED_CODE_RTL(); 00553 00554 RtlpQuerySecurityDescriptor(pAbsSD, 00555 &Owner, 00556 &OwnerLength, 00557 &Group, 00558 &GroupLength, 00559 &Dacl, 00560 &DaclLength, 00561 &Sacl, 00562 &SaclLength); 00563 00564 TotalLength = sizeof(SECURITY_DESCRIPTOR_RELATIVE) + OwnerLength + GroupLength + SaclLength + DaclLength; 00565 if (*BufferLength < TotalLength) 00566 { 00567 *BufferLength = TotalLength; 00568 return STATUS_BUFFER_TOO_SMALL; 00569 } 00570 00571 RtlZeroMemory(pRelSD, 00572 TotalLength); 00573 00574 pRelSD->Revision = pAbsSD->Revision; 00575 pRelSD->Sbz1 = pAbsSD->Sbz1; 00576 pRelSD->Control = pAbsSD->Control | SE_SELF_RELATIVE; 00577 00578 Current = (ULONG_PTR)(pRelSD + 1); 00579 00580 if (SaclLength != 0) 00581 { 00582 RtlCopyMemory((PVOID)Current, 00583 Sacl, 00584 SaclLength); 00585 pRelSD->Sacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD); 00586 Current += SaclLength; 00587 } 00588 00589 if (DaclLength != 0) 00590 { 00591 RtlCopyMemory((PVOID)Current, 00592 Dacl, 00593 DaclLength); 00594 pRelSD->Dacl = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD); 00595 Current += DaclLength; 00596 } 00597 00598 if (OwnerLength != 0) 00599 { 00600 RtlCopyMemory((PVOID)Current, 00601 Owner, 00602 OwnerLength); 00603 pRelSD->Owner = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD); 00604 Current += OwnerLength; 00605 } 00606 00607 if (GroupLength != 0) 00608 { 00609 RtlCopyMemory((PVOID)Current, 00610 Group, 00611 GroupLength); 00612 pRelSD->Group = (ULONG)((ULONG_PTR)Current - (ULONG_PTR)pRelSD); 00613 } 00614 00615 return STATUS_SUCCESS; 00616 } 00617 00618 00619 /* 00620 * @implemented 00621 */ 00622 NTSTATUS NTAPI 00623 RtlAbsoluteToSelfRelativeSD(IN PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor, 00624 IN OUT PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor, 00625 IN PULONG BufferLength) 00626 { 00627 PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSecurityDescriptor; 00628 00629 PAGED_CODE_RTL(); 00630 00631 if (pAbsSD->Control & SE_SELF_RELATIVE) 00632 { 00633 return STATUS_BAD_DESCRIPTOR_FORMAT; 00634 } 00635 00636 return RtlMakeSelfRelativeSD(AbsoluteSecurityDescriptor, 00637 SelfRelativeSecurityDescriptor, 00638 BufferLength); 00639 } 00640 00641 00642 /* 00643 * @implemented 00644 */ 00645 NTSTATUS NTAPI 00646 RtlGetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00647 OUT PSECURITY_DESCRIPTOR_CONTROL Control, 00648 OUT PULONG Revision) 00649 { 00650 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00651 00652 PAGED_CODE_RTL(); 00653 00654 *Revision = pSD->Revision; 00655 00656 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00657 { 00658 return STATUS_UNKNOWN_REVISION; 00659 } 00660 00661 *Control = pSD->Control; 00662 00663 return STATUS_SUCCESS; 00664 } 00665 00666 00667 /* 00668 * @implemented 00669 */ 00670 NTSTATUS NTAPI 00671 RtlSetControlSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00672 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest, 00673 IN SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet) 00674 { 00675 SECURITY_DESCRIPTOR_CONTROL const immutable 00676 = SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED 00677 | SE_DACL_PRESENT | SE_DACL_DEFAULTED 00678 | SE_SACL_PRESENT | SE_SACL_DEFAULTED 00679 | SE_RM_CONTROL_VALID | SE_SELF_RELATIVE 00680 ; 00681 00682 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00683 00684 PAGED_CODE_RTL(); 00685 00686 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00687 { 00688 return STATUS_UNKNOWN_REVISION; 00689 } 00690 00691 if ((ControlBitsOfInterest | ControlBitsToSet) & immutable) 00692 return STATUS_INVALID_PARAMETER; 00693 00694 /* Zero the 'bits of interest' */ 00695 pSD->Control &= ~ControlBitsOfInterest; 00696 00697 /* Set the 'bits to set' */ 00698 pSD->Control |= (ControlBitsToSet & ControlBitsOfInterest); 00699 00700 return STATUS_SUCCESS; 00701 } 00702 00703 00704 /* 00705 * @implemented 00706 */ 00707 NTSTATUS NTAPI 00708 RtlGetSaclSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 00709 OUT PBOOLEAN SaclPresent, 00710 OUT PACL *Sacl, 00711 OUT PBOOLEAN SaclDefaulted) 00712 { 00713 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00714 00715 PAGED_CODE_RTL(); 00716 00717 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00718 { 00719 return STATUS_UNKNOWN_REVISION; 00720 } 00721 00722 if (!(pSD->Control & SE_SACL_PRESENT)) 00723 { 00724 *SaclPresent = FALSE; 00725 return STATUS_SUCCESS; 00726 } 00727 *SaclPresent = TRUE; 00728 00729 RtlpQuerySecurityDescriptorPointers(pSD, 00730 NULL, 00731 NULL, 00732 Sacl, 00733 NULL); 00734 00735 *SaclDefaulted = ((pSD->Control & SE_SACL_DEFAULTED) ? TRUE : FALSE); 00736 00737 return STATUS_SUCCESS; 00738 } 00739 00740 00741 /* 00742 * @implemented 00743 */ 00744 NTSTATUS NTAPI 00745 RtlSetSaclSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 00746 IN BOOLEAN SaclPresent, 00747 IN PACL Sacl, 00748 IN BOOLEAN SaclDefaulted) 00749 { 00750 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 00751 00752 PAGED_CODE_RTL(); 00753 00754 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00755 { 00756 return STATUS_UNKNOWN_REVISION; 00757 } 00758 00759 if (pSD->Control & SE_SELF_RELATIVE) 00760 { 00761 return STATUS_BAD_DESCRIPTOR_FORMAT; 00762 } 00763 00764 if (!SaclPresent) 00765 { 00766 pSD->Control &= ~(SE_SACL_PRESENT); 00767 return STATUS_SUCCESS; 00768 } 00769 00770 pSD->Sacl = Sacl; 00771 pSD->Control |= SE_SACL_PRESENT; 00772 pSD->Control &= ~(SE_SACL_DEFAULTED); 00773 00774 if (SaclDefaulted) 00775 { 00776 pSD->Control |= SE_SACL_DEFAULTED; 00777 } 00778 00779 return STATUS_SUCCESS; 00780 } 00781 00782 00783 /* 00784 * @implemented 00785 */ 00786 NTSTATUS NTAPI 00787 RtlSelfRelativeToAbsoluteSD(IN PSECURITY_DESCRIPTOR SelfRelativeSD, 00788 OUT PSECURITY_DESCRIPTOR AbsoluteSD, 00789 IN PULONG AbsoluteSDSize, 00790 IN PACL Dacl, 00791 IN PULONG DaclSize, 00792 IN PACL Sacl, 00793 IN PULONG SaclSize, 00794 IN PSID Owner, 00795 IN PULONG OwnerSize, 00796 IN PSID PrimaryGroup, 00797 IN PULONG PrimaryGroupSize) 00798 { 00799 PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)AbsoluteSD; 00800 PISECURITY_DESCRIPTOR pRelSD = (PISECURITY_DESCRIPTOR)SelfRelativeSD; 00801 ULONG OwnerLength; 00802 ULONG GroupLength; 00803 ULONG DaclLength; 00804 ULONG SaclLength; 00805 PSID pOwner; 00806 PSID pGroup; 00807 PACL pDacl; 00808 PACL pSacl; 00809 00810 PAGED_CODE_RTL(); 00811 00812 if (pRelSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00813 { 00814 return STATUS_UNKNOWN_REVISION; 00815 } 00816 00817 if (!(pRelSD->Control & SE_SELF_RELATIVE)) 00818 { 00819 return STATUS_BAD_DESCRIPTOR_FORMAT; 00820 } 00821 00822 RtlpQuerySecurityDescriptor (pRelSD, 00823 &pOwner, 00824 &OwnerLength, 00825 &pGroup, 00826 &GroupLength, 00827 &pDacl, 00828 &DaclLength, 00829 &pSacl, 00830 &SaclLength); 00831 00832 if (OwnerLength > *OwnerSize || 00833 GroupLength > *PrimaryGroupSize || 00834 DaclLength > *DaclSize || 00835 SaclLength > *SaclSize) 00836 { 00837 *OwnerSize = OwnerLength; 00838 *PrimaryGroupSize = GroupLength; 00839 *DaclSize = DaclLength; 00840 *SaclSize = SaclLength; 00841 return STATUS_BUFFER_TOO_SMALL; 00842 } 00843 00844 RtlCopyMemory (Owner, pOwner, OwnerLength); 00845 RtlCopyMemory (PrimaryGroup, pGroup, GroupLength); 00846 RtlCopyMemory (Dacl, pDacl, DaclLength); 00847 RtlCopyMemory (Sacl, pSacl, SaclLength); 00848 00849 pAbsSD->Revision = pRelSD->Revision; 00850 pAbsSD->Sbz1 = pRelSD->Sbz1; 00851 pAbsSD->Control = pRelSD->Control & ~SE_SELF_RELATIVE; 00852 pAbsSD->Owner = Owner; 00853 pAbsSD->Group = PrimaryGroup; 00854 pAbsSD->Dacl = Dacl; 00855 pAbsSD->Sacl = Sacl; 00856 00857 *OwnerSize = OwnerLength; 00858 *PrimaryGroupSize = GroupLength; 00859 *DaclSize = DaclLength; 00860 *SaclSize = SaclLength; 00861 00862 return STATUS_SUCCESS; 00863 } 00864 00865 00866 /* 00867 * @implemented 00868 */ 00869 NTSTATUS NTAPI 00870 RtlSelfRelativeToAbsoluteSD2(IN OUT PSECURITY_DESCRIPTOR SelfRelativeSD, 00871 OUT PULONG BufferSize) 00872 { 00873 PISECURITY_DESCRIPTOR pAbsSD = (PISECURITY_DESCRIPTOR)SelfRelativeSD; 00874 PISECURITY_DESCRIPTOR_RELATIVE pRelSD = (PISECURITY_DESCRIPTOR_RELATIVE)SelfRelativeSD; 00875 #ifdef _WIN64 00876 PVOID DataStart, DataEnd; 00877 ULONG DataSize; 00878 LONG MoveDelta; 00879 ULONG OwnerLength; 00880 ULONG GroupLength; 00881 ULONG DaclLength; 00882 ULONG SaclLength; 00883 #endif 00884 PSID pOwner; 00885 PSID pGroup; 00886 PACL pDacl; 00887 PACL pSacl; 00888 00889 PAGED_CODE_RTL(); 00890 00891 if (SelfRelativeSD == NULL) 00892 { 00893 return STATUS_INVALID_PARAMETER_1; 00894 } 00895 if (BufferSize == NULL) 00896 { 00897 return STATUS_INVALID_PARAMETER_2; 00898 } 00899 00900 if (pRelSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 00901 { 00902 return STATUS_UNKNOWN_REVISION; 00903 } 00904 if (!(pRelSD->Control & SE_SELF_RELATIVE)) 00905 { 00906 return STATUS_BAD_DESCRIPTOR_FORMAT; 00907 } 00908 00909 #ifdef _WIN64 00910 00911 RtlpQuerySecurityDescriptor((PISECURITY_DESCRIPTOR)pRelSD, 00912 &pOwner, 00913 &OwnerLength, 00914 &pGroup, 00915 &GroupLength, 00916 &pDacl, 00917 &DaclLength, 00918 &pSacl, 00919 &SaclLength); 00920 00921 /* calculate the start and end of the data area, we simply just move the 00922 data by the difference between the size of the relative and absolute 00923 security descriptor structure */ 00924 DataStart = pOwner; 00925 DataEnd = (PVOID)((ULONG_PTR)pOwner + OwnerLength); 00926 if (pGroup != NULL) 00927 { 00928 if (((ULONG_PTR)pGroup < (ULONG_PTR)DataStart) || DataStart == NULL) 00929 DataStart = pGroup; 00930 if (((ULONG_PTR)pGroup + GroupLength > (ULONG_PTR)DataEnd) || DataEnd == NULL) 00931 DataEnd = (PVOID)((ULONG_PTR)pGroup + GroupLength); 00932 } 00933 if (pDacl != NULL) 00934 { 00935 if (((ULONG_PTR)pDacl < (ULONG_PTR)DataStart) || DataStart == NULL) 00936 DataStart = pDacl; 00937 if (((ULONG_PTR)pDacl + DaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL) 00938 DataEnd = (PVOID)((ULONG_PTR)pDacl + DaclLength); 00939 } 00940 if (pSacl != NULL) 00941 { 00942 if (((ULONG_PTR)pSacl < (ULONG_PTR)DataStart) || DataStart == NULL) 00943 DataStart = pSacl; 00944 if (((ULONG_PTR)pSacl + SaclLength > (ULONG_PTR)DataEnd) || DataEnd == NULL) 00945 DataEnd = (PVOID)((ULONG_PTR)pSacl + SaclLength); 00946 } 00947 00948 ASSERT((ULONG_PTR)DataEnd >= (ULONG_PTR)DataStart); 00949 00950 DataSize = (ULONG)((ULONG_PTR)DataEnd - (ULONG_PTR)DataStart); 00951 00952 if (*BufferSize < sizeof(SECURITY_DESCRIPTOR) + DataSize) 00953 { 00954 *BufferSize = sizeof(SECURITY_DESCRIPTOR) + DataSize; 00955 return STATUS_BUFFER_TOO_SMALL; 00956 } 00957 00958 if (DataSize != 0) 00959 { 00960 /* if DataSize != 0 ther must be at least one SID or ACL in the security 00961 descriptor! Also the data area must be located somewhere after the 00962 end of the SECURITY_DESCRIPTOR_RELATIVE structure */ 00963 ASSERT(DataStart != NULL); 00964 ASSERT((ULONG_PTR)DataStart >= (ULONG_PTR)(pRelSD + 1)); 00965 00966 /* it's time to move the data */ 00967 RtlMoveMemory((PVOID)(pAbsSD + 1), 00968 DataStart, 00969 DataSize); 00970 00971 MoveDelta = (LONG)((LONG_PTR)(pAbsSD + 1) - (LONG_PTR)DataStart); 00972 00973 /* adjust the pointers if neccessary */ 00974 if (pOwner != NULL) 00975 pAbsSD->Owner = (PSID)((LONG_PTR)pOwner + MoveDelta); 00976 else 00977 pAbsSD->Owner = NULL; 00978 00979 if (pGroup != NULL) 00980 pAbsSD->Group = (PSID)((LONG_PTR)pGroup + MoveDelta); 00981 else 00982 pAbsSD->Group = NULL; 00983 00984 if (pSacl != NULL) 00985 pAbsSD->Sacl = (PACL)((LONG_PTR)pSacl + MoveDelta); 00986 else 00987 pAbsSD->Sacl = NULL; 00988 00989 if (pDacl != NULL) 00990 pAbsSD->Dacl = (PACL)((LONG_PTR)pDacl + MoveDelta); 00991 else 00992 pAbsSD->Dacl = NULL; 00993 } 00994 else 00995 { 00996 /* all pointers must be NULL! */ 00997 ASSERT(pOwner == NULL); 00998 ASSERT(pGroup == NULL); 00999 ASSERT(pSacl == NULL); 01000 ASSERT(pDacl == NULL); 01001 01002 pAbsSD->Owner = NULL; 01003 pAbsSD->Group = NULL; 01004 pAbsSD->Sacl = NULL; 01005 pAbsSD->Dacl = NULL; 01006 } 01007 01008 /* clear the self-relative flag */ 01009 pAbsSD->Control &= ~SE_SELF_RELATIVE; 01010 01011 #else 01012 01013 RtlpQuerySecurityDescriptorPointers((PISECURITY_DESCRIPTOR)pRelSD, 01014 &pOwner, 01015 &pGroup, 01016 &pSacl, 01017 &pDacl); 01018 01019 /* clear the self-relative flag and simply convert the offsets to pointers */ 01020 pAbsSD->Control &= ~SE_SELF_RELATIVE; 01021 pAbsSD->Owner = pOwner; 01022 pAbsSD->Group = pGroup; 01023 pAbsSD->Sacl = pSacl; 01024 pAbsSD->Dacl = pDacl; 01025 01026 #endif 01027 01028 return STATUS_SUCCESS; 01029 } 01030 01031 01032 /* 01033 * @implemented 01034 */ 01035 BOOLEAN NTAPI 01036 RtlValidRelativeSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptorInput, 01037 IN ULONG SecurityDescriptorLength, 01038 IN SECURITY_INFORMATION RequiredInformation) 01039 { 01040 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptorInput; 01041 01042 PAGED_CODE_RTL(); 01043 01044 if (SecurityDescriptorLength < sizeof(SECURITY_DESCRIPTOR_RELATIVE) || 01045 pSD->Revision != SECURITY_DESCRIPTOR_REVISION1 || 01046 !(pSD->Control & SE_SELF_RELATIVE)) 01047 { 01048 return FALSE; 01049 } 01050 01051 if (pSD->Owner != 0) 01052 { 01053 PSID Owner = (PSID)((ULONG_PTR)pSD->Owner + (ULONG_PTR)pSD); 01054 if (!RtlValidSid(Owner)) 01055 { 01056 return FALSE; 01057 } 01058 } 01059 else if (RequiredInformation & OWNER_SECURITY_INFORMATION) 01060 { 01061 return FALSE; 01062 } 01063 01064 if (pSD->Group != 0) 01065 { 01066 PSID Group = (PSID)((ULONG_PTR)pSD->Group + (ULONG_PTR)pSD); 01067 if (!RtlValidSid(Group)) 01068 { 01069 return FALSE; 01070 } 01071 } 01072 else if (RequiredInformation & GROUP_SECURITY_INFORMATION) 01073 { 01074 return FALSE; 01075 } 01076 01077 if (pSD->Control & SE_DACL_PRESENT) 01078 { 01079 if (pSD->Dacl != 0 && 01080 !RtlValidAcl((PACL)((ULONG_PTR)pSD->Dacl + (ULONG_PTR)pSD))) 01081 { 01082 return FALSE; 01083 } 01084 } 01085 else if (RequiredInformation & DACL_SECURITY_INFORMATION) 01086 { 01087 return FALSE; 01088 } 01089 01090 if (pSD->Control & SE_SACL_PRESENT) 01091 { 01092 if (pSD->Sacl != 0 && 01093 !RtlValidAcl((PACL)((ULONG_PTR)pSD->Sacl + (ULONG_PTR)pSD))) 01094 { 01095 return FALSE; 01096 } 01097 } 01098 else if (RequiredInformation & SACL_SECURITY_INFORMATION) 01099 { 01100 return FALSE; 01101 } 01102 01103 return TRUE; 01104 } 01105 01106 01107 /* 01108 * @implemented 01109 */ 01110 BOOLEAN NTAPI 01111 RtlGetSecurityDescriptorRMControl(IN PSECURITY_DESCRIPTOR SecurityDescriptor, 01112 OUT PUCHAR RMControl) 01113 { 01114 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 01115 01116 PAGED_CODE_RTL(); 01117 01118 if (!(pSD->Control & SE_RM_CONTROL_VALID)) 01119 { 01120 *RMControl = 0; 01121 return FALSE; 01122 } 01123 01124 *RMControl = pSD->Sbz1; 01125 01126 return TRUE; 01127 } 01128 01129 01130 /* 01131 * @implemented 01132 */ 01133 VOID NTAPI 01134 RtlSetSecurityDescriptorRMControl(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 01135 IN PUCHAR RMControl) 01136 { 01137 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 01138 01139 PAGED_CODE_RTL(); 01140 01141 if (RMControl == NULL) 01142 { 01143 pSD->Control &= ~SE_RM_CONTROL_VALID; 01144 pSD->Sbz1 = 0; 01145 } 01146 else 01147 { 01148 pSD->Control |= SE_RM_CONTROL_VALID; 01149 pSD->Sbz1 = *RMControl; 01150 } 01151 } 01152 01153 01154 /* 01155 * @implemented 01156 */ 01157 NTSTATUS NTAPI 01158 RtlSetAttributesSecurityDescriptor(IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, 01159 IN SECURITY_DESCRIPTOR_CONTROL Control, 01160 OUT PULONG Revision) 01161 { 01162 PISECURITY_DESCRIPTOR pSD = (PISECURITY_DESCRIPTOR)SecurityDescriptor; 01163 01164 PAGED_CODE_RTL(); 01165 01166 *Revision = pSD->Revision; 01167 01168 if (pSD->Revision != SECURITY_DESCRIPTOR_REVISION1) 01169 return STATUS_UNKNOWN_REVISION; 01170 01171 Control &= 01172 ~(SE_OWNER_DEFAULTED | SE_GROUP_DEFAULTED | SE_DACL_PRESENT | 01173 SE_DACL_DEFAULTED | SE_SACL_PRESENT | SE_SACL_DEFAULTED | 01174 SE_RM_CONTROL_VALID | SE_SELF_RELATIVE); 01175 01176 return RtlSetControlSecurityDescriptor(SecurityDescriptor, 01177 Control, 01178 Control); 01179 } 01180 01181 /* EOF */ Generated on Thu May 24 2012 04:36:54 for ReactOS by
1.7.6.1
|